@@ -75,6 +75,14 @@ type Stream struct {
75
75
//
76
76
// Note: Calls to KeyToList are concurrent.
77
77
KeyToList func (key []byte , itr * Iterator ) (* pb.KVList , error )
78
+ // UseKeyToListWithThreadId is used to indicate that KeyToListWithThreadId should be used
79
+ // instead of KeyToList. This is a new api that can be used to figure out parallelism
80
+ // of the stream. Each threadId would be run serially. KeyToList being concurrent makes you
81
+ // take care of concurrency in KeyToList. Here threadId could be used to do some things serially.
82
+ // Once a thread finishes FinishThread() would be called.
83
+ UseKeyToListWithThreadId bool
84
+ KeyToListWithThreadId func (key []byte , itr * Iterator , threadId int ) (* pb.KVList , error )
85
+ FinishThread func (threadId int ) (* pb.KVList , error )
78
86
79
87
// This is the method where Stream sends the final output. All calls to Send are done by a
80
88
// single goroutine, i.e. logic within Send method can expect single threaded execution.
@@ -143,7 +151,7 @@ func (st *Stream) ToList(key []byte, itr *Iterator) (*pb.KVList, error) {
143
151
// keyRange is [start, end), including start, excluding end. Do ensure that the start,
144
152
// end byte slices are owned by keyRange struct.
145
153
func (st * Stream ) produceRanges (ctx context.Context ) {
146
- ranges := st .db .Ranges (st .Prefix , 16 )
154
+ ranges := st .db .Ranges (st .Prefix , st . NumGo )
147
155
y .AssertTrue (len (ranges ) > 0 )
148
156
y .AssertTrue (ranges [0 ].left == nil )
149
157
y .AssertTrue (ranges [len (ranges )- 1 ].right == nil )
@@ -186,7 +194,7 @@ func (st *Stream) produceKVs(ctx context.Context, threadId int) error {
186
194
iterOpts := DefaultIteratorOptions
187
195
iterOpts .AllVersions = true
188
196
iterOpts .Prefix = st .Prefix
189
- iterOpts .PrefetchValues = false
197
+ iterOpts .PrefetchValues = true
190
198
iterOpts .SinceTs = st .SinceTs
191
199
itr := txn .NewIterator (iterOpts )
192
200
itr .ThreadId = threadId
@@ -233,7 +241,13 @@ func (st *Stream) produceKVs(ctx context.Context, threadId int) error {
233
241
234
242
// Now convert to key value.
235
243
itr .Alloc .Reset ()
236
- list , err := st .KeyToList (item .KeyCopy (nil ), itr )
244
+ var list * pb.KVList
245
+ var err error
246
+ if st .UseKeyToListWithThreadId {
247
+ list , err = st .KeyToListWithThreadId (item .KeyCopy (nil ), itr , threadId )
248
+ } else {
249
+ list , err = st .KeyToList (item .KeyCopy (nil ), itr )
250
+ }
237
251
if err != nil {
238
252
st .db .opt .Warningf ("While reading key: %x, got error: %v" , item .Key (), err )
239
253
continue
@@ -252,6 +266,23 @@ func (st *Stream) produceKVs(ctx context.Context, threadId int) error {
252
266
}
253
267
}
254
268
}
269
+
270
+ if st .UseKeyToListWithThreadId {
271
+ if kvs , err := st .FinishThread (threadId ); err != nil {
272
+ return err
273
+ } else {
274
+ for _ , kv := range kvs .Kv {
275
+ kv .StreamId = streamId
276
+ KVToBuffer (kv , outList )
277
+ if outList .LenNoPadding () < batchSize {
278
+ continue
279
+ }
280
+ if err := sendIt (); err != nil {
281
+ return err
282
+ }
283
+ }
284
+ }
285
+ }
255
286
// Mark the stream as done.
256
287
if st .doneMarkers {
257
288
kv := & pb.KV {
0 commit comments