@@ -258,11 +258,6 @@ func (txn *Txn) DeleteAll(table, index string, args ...interface{}) (int, error)
258
258
return 0 , fmt .Errorf ("cannot delete in read-only transaction" )
259
259
}
260
260
261
- // TODO: Currently we use Get to just every object and then
262
- // iterate and delete them all. This works because sliceIterator
263
- // has the full result set, but we may need to handle the iteraction
264
- // between the iterator and delete in the future.
265
-
266
261
// Get all the objects
267
262
iter , err := txn .Get (table , index , args ... )
268
263
if err != nil {
@@ -383,19 +378,15 @@ func (txn *Txn) Get(table, index string, args ...interface{}) (ResultIterator, e
383
378
indexTxn := txn .readableIndex (table , indexSchema .Name )
384
379
indexRoot := indexTxn .Root ()
385
380
386
- // Collect all the objects by walking the prefix. This should obviously
387
- // be optimized by using an iterator over the radix tree, but that is
388
- // a lot more work so its a TODO for now.
389
- var results []interface {}
390
- indexRoot .WalkPrefix (val , func (key []byte , val interface {}) bool {
391
- results = append (results , val )
392
- return false
393
- })
381
+ // Get an interator over the index
382
+ indexIter := indexRoot .Iterator ()
383
+
384
+ // Seek the iterator to the appropriate sub-set
385
+ indexIter .SeekPrefix (val )
394
386
395
- // Create a crappy iterator
396
- iter := & sliceIterator {
397
- nextIndex : 0 ,
398
- results : results ,
387
+ // Create an iterator
388
+ iter := & radixIterator {
389
+ iter : indexIter ,
399
390
}
400
391
return iter , nil
401
392
}
@@ -408,19 +399,17 @@ func (txn *Txn) Defer(fn func()) {
408
399
txn .after = append (txn .after , fn )
409
400
}
410
401
411
- // Slice iterator is used to iterate over a slice of results.
412
- // This is not very efficient as it means the results have already
413
- // been materialized under the iterator.
414
- type sliceIterator struct {
415
- nextIndex int
416
- results []interface {}
402
+ // radixIterator is used to wrap an underlying iradix iterator.
403
+ // This is much mroe efficient than a sliceIterator as we are not
404
+ // materializing the entire view.
405
+ type radixIterator struct {
406
+ iter * iradix.Iterator
417
407
}
418
408
419
- func (s * sliceIterator ) Next () interface {} {
420
- if s .nextIndex >= len (s .results ) {
409
+ func (r * radixIterator ) Next () interface {} {
410
+ _ , value , ok := r .iter .Next ()
411
+ if ! ok {
421
412
return nil
422
413
}
423
- result := s .results [s .nextIndex ]
424
- s .nextIndex ++
425
- return result
414
+ return value
426
415
}
0 commit comments