@@ -63,7 +63,8 @@ func (f *flusher) run() (err error) {
63
63
64
64
f .debugf ("Processing %s" , f .goal )
65
65
seen := make (map [bson.ObjectId ]* transaction )
66
- if err := f .recurse (f .goal , seen ); err != nil {
66
+ preloaded := make (map [bson.ObjectId ]* transaction )
67
+ if err := f .recurse (f .goal , seen , preloaded ); err != nil {
67
68
return err
68
69
}
69
70
if f .goal .done () {
@@ -155,26 +156,54 @@ func (f *flusher) run() (err error) {
155
156
return nil
156
157
}
157
158
158
- func (f * flusher ) recurse (t * transaction , seen map [bson.ObjectId ]* transaction ) error {
159
+ const preloadBatchSize = 100
160
+
161
+ func (f * flusher ) recurse (t * transaction , seen map [bson.ObjectId ]* transaction , preloaded map [bson.ObjectId ]* transaction ) error {
159
162
seen [t .Id ] = t
163
+ delete (preloaded , t .Id )
160
164
err := f .advance (t , nil , false )
161
165
if err != errPreReqs {
162
166
return err
163
167
}
164
168
for _ , dkey := range t .docKeys () {
169
+ remaining := make ([]bson.ObjectId , 0 , len (f .queue [dkey ]))
170
+ toPreload := make (map [bson.ObjectId ]struct {}, len (f .queue [dkey ]))
165
171
for _ , dtt := range f .queue [dkey ] {
166
172
id := dtt .id ()
167
- if seen [id ] != nil {
173
+ if _ , scheduled := toPreload [ id ]; seen [ id ] != nil || scheduled || preloaded [id ] != nil {
168
174
continue
169
175
}
170
- qt , err := f .load (id )
171
- if err != nil {
172
- return err
176
+ toPreload [id ] = struct {}{}
177
+ remaining = append (remaining , id )
178
+ }
179
+ // done with this map
180
+ toPreload = nil
181
+ for len (remaining ) > 0 {
182
+ batch := remaining
183
+ if len (batch ) > preloadBatchSize {
184
+ batch = remaining [:preloadBatchSize ]
173
185
}
174
- err = f .recurse (qt , seen )
186
+ remaining = remaining [len (batch ):]
187
+ err := f .loadMulti (batch , preloaded )
175
188
if err != nil {
176
189
return err
177
190
}
191
+ for _ , id := range batch {
192
+ if seen [id ] != nil {
193
+ continue
194
+ }
195
+ qt , ok := preloaded [id ]
196
+ if ! ok {
197
+ qt , err = f .load (id )
198
+ if err != nil {
199
+ return err
200
+ }
201
+ }
202
+ err = f .recurse (qt , seen , preloaded )
203
+ if err != nil {
204
+ return err
205
+ }
206
+ }
178
207
}
179
208
}
180
209
return nil
0 commit comments