-
Notifications
You must be signed in to change notification settings - Fork 50
/
batch.go
62 lines (45 loc) · 1.32 KB
/
batch.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package kvstore
import (
"context"
"fmt"
"github.com/justtrackio/gosoline/pkg/refl"
)
func keyChunks(keys []interface{}, size int) [][]interface{} {
var chunks [][]interface{}
for i := 0; i < len(keys); i += size {
end := i + size
if end > len(keys) {
end = len(keys)
}
chunks = append(chunks, keys[i:end])
}
return chunks
}
type chunkGetter func(ctx context.Context, resultMap *refl.Map, keys []interface{}) ([]interface{}, error)
func getBatch(ctx context.Context, keys interface{}, result interface{}, getChunk chunkGetter, batchSize int) ([]interface{}, error) {
keySlice, err := refl.InterfaceToInterfaceSlice(keys)
if err != nil {
return nil, fmt.Errorf("can not morph keys to slice of interfaces: %w", err)
}
keySlice, err = UniqKeys(keySlice)
if err != nil {
return nil, fmt.Errorf("can not deduplicate keys: %w", err)
}
resultMap, err := refl.MapOf(result)
if err != nil {
return keySlice, fmt.Errorf("can not use provided result value: %w", err)
}
if batchSize < 1 {
batchSize = 1
}
chunks := keyChunks(keySlice, batchSize)
missing := make([]interface{}, 0)
for _, chunk := range chunks {
miss, err := getChunk(ctx, resultMap, chunk)
if err != nil {
return keySlice, fmt.Errorf("can not get chunk: %w", err)
}
missing = append(missing, miss...)
}
return missing, nil
}