Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(376)

Unified Diff: filter/dsQueryBatch/filter.go

Issue 1843313004: Add datastore iterating query filter. (Closed) Base URL: https://chromium.googlesource.com/external/github.com/luci/gae@no-stop-in-raw
Patch Set: Add test. Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: filter/dsQueryBatch/filter.go
diff --git a/filter/dsQueryBatch/filter.go b/filter/dsQueryBatch/filter.go
new file mode 100644
index 0000000000000000000000000000000000000000..5555218d77880ba8a627126a36944914f3a96579
--- /dev/null
+++ b/filter/dsQueryBatch/filter.go
@@ -0,0 +1,82 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package dsQueryBatch
+
+import (
+ "fmt"
+
+ ds "github.com/luci/gae/service/datastore"
+)
+
+type iterQueryFilter struct {
+ ds.RawInterface
+
+ batchSize int32
+}
+
+func (f *iterQueryFilter) Run(fq *ds.FinalizedQuery, cb ds.RawRunCB) error {
+ limit, hasLimit := fq.Limit()
+
+ var cursor ds.Cursor
+ for {
+ iterQuery := fq.Original()
+ if cursor != nil {
+ iterQuery = iterQuery.Start(cursor)
+ cursor = nil
+ }
+ iterLimit := f.batchSize
+ if hasLimit && limit < iterLimit {
+ iterLimit = limit
+ }
+ iterQuery = iterQuery.Limit(iterLimit)
+
+ iterFinalizedQuery, err := iterQuery.Finalize()
+ if err != nil {
+ return fmt.Errorf("failed to finalize internal query: %v", err)
iannucci 2016/03/31 22:40:31 panic: this can't fail if we started with a Finali
dnj 2016/03/31 23:54:06 Done.
+ }
+
+ count := int32(0)
+ err = f.RawInterface.Run(iterFinalizedQuery, func(key *ds.Key, val ds.PropertyMap, getCursor ds.CursorCB) error {
+ if cursor != nil {
+ // We're iterating past our batch size, which should never happen, since
+ // we set a limit.
+ return fmt.Errorf("iterating past batch size")
iannucci 2016/03/31 22:40:30 yeah let's panic here too. maybe more comment expl
dnj 2016/03/31 23:54:06 Done.
+ }
+
+ // Call backing iterator.
iannucci 2016/03/31 22:40:30 doesn't need a comment
dnj 2016/03/31 23:54:06 Done.
+ if err := cb(key, val, getCursor); err != nil {
+ return err
+ }
+
+ // If this is the last entry in our batch, get the cursor and stop this
+ // query round.
+ count++
+ if count >= f.batchSize {
+ cursor, err = getCursor()
+ if err != nil {
iannucci 2016/03/31 22:40:31 if cursor, err = .......; .... {
+ return fmt.Errorf("failed to get cursor: %v", err)
+ }
+ }
+ return nil
+ })
+ if err != nil && err != ds.Stop {
+ return err
+ }
+
+ // If we have no cursor, we're done.
+ if cursor == nil {
+ break
+ }
+
+ // Reduce our limit for the next round.
+ if hasLimit {
+ limit -= count
+ if limit <= 0 {
+ break
+ }
+ }
+ }
+ return nil
+}

Powered by Google App Engine
This is Rietveld 408576698