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

Side by Side Diff: impl/memory/gkvlite_iter.go

Issue 1521823003: Clean up callback interfaces. (Closed) Base URL: https://github.com/luci/gae.git@extra
Patch Set: Created 5 years 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 unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package memory 5 package memory
6 6
7 import ( 7 import (
8 "bytes" 8 "bytes"
9 "sync" 9 "sync"
10 10
11 "github.com/luci/gae/service/datastore"
11 "github.com/luci/gae/service/datastore/serialize" 12 "github.com/luci/gae/service/datastore/serialize"
12 "github.com/luci/gkvlite" 13 "github.com/luci/gkvlite"
13 ) 14 )
14 15
15 type iterDefinition struct { 16 type iterDefinition struct {
16 // The collection to iterate over 17 // The collection to iterate over
17 c *memCollection 18 c *memCollection
18 19
19 // The prefix to always assert for every row. A nil prefix matches every row. 20 // The prefix to always assert for every row. A nil prefix matches every row.
20 prefix []byte 21 prefix []byte
21 22
22 // prefixLen is the number of prefix bytes that the caller cares about. It 23 // prefixLen is the number of prefix bytes that the caller cares about. It
23 // may be <= len(prefix). When doing a multiIterator, this number will b e used 24 // may be <= len(prefix). When doing a multiIterator, this number will b e used
24 // to determine the amount of suffix to transfer accross iterators. This is 25 // to determine the amount of suffix to transfer accross iterators. This is
25 // used specifically when using builtin indexes to service ancestor quer ies. 26 // used specifically when using builtin indexes to service ancestor quer ies.
26 // The builtin index represents the ancestor key with prefix bytes, but in a 27 // The builtin index represents the ancestor key with prefix bytes, but in a
27 // multiIterator context, it wants the entire key to be included in the 28 // multiIterator context, it wants the entire key to be included in the
28 // suffix. 29 // suffix.
29 prefixLen int 30 prefixLen int
30 31
31 // The start cursor. It's appended to prefix to find the first row. 32 // The start cursor. It's appended to prefix to find the first row.
32 start []byte 33 start []byte
33 34
34 // The end cursor. It's appended to prefix to find the last row (which i s not 35 // The end cursor. It's appended to prefix to find the last row (which i s not
35 // included in the interation result). If this is nil, then there's no e nd 36 // included in the interation result). If this is nil, then there's no e nd
36 // except the natural end of the collection. 37 // except the natural end of the collection.
37 end []byte 38 end []byte
38 } 39 }
39 40
40 func multiIterate(defs []*iterDefinition, cb func(suffix []byte) bool) { 41 func multiIterate(defs []*iterDefinition, cb func(suffix []byte) error) error {
41 if len(defs) == 0 { 42 if len(defs) == 0 {
42 » » return 43 » » return nil
43 } 44 }
44 45
45 ts := make([]*iterator, len(defs)) 46 ts := make([]*iterator, len(defs))
46 prefixLens := make([]int, len(defs)) 47 prefixLens := make([]int, len(defs))
47 for i, def := range defs { 48 for i, def := range defs {
48 // bind i so that the defer below doesn't get goofed by the loop variable 49 // bind i so that the defer below doesn't get goofed by the loop variable
49 i := i 50 i := i
50 ts[i] = def.mkIter() 51 ts[i] = def.mkIter()
51 prefixLens[i] = def.prefixLen 52 prefixLens[i] = def.prefixLen
52 defer ts[i].stop() 53 defer ts[i].stop()
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 // no point to restarting on the 0th index 86 // no point to restarting on the 0th index
86 restart = true 87 restart = true
87 } 88 }
88 } 89 }
89 }) 90 })
90 if stop || restart { 91 if stop || restart {
91 break 92 break
92 } 93 }
93 } 94 }
94 if stop { 95 if stop {
95 » » » return 96 » » » return nil
96 } 97 }
97 if restart { 98 if restart {
98 continue 99 continue
99 } 100 }
100 101
101 » » if !cb(suffix) { 102 » » if err := cb(suffix); err != nil {
102 » » » return 103 » » » if err == datastore.Stop {
104 » » » » err = nil
dnj 2015/12/14 22:35:02 WDYT about just "return nil" here and elsewhere th
iannucci 2015/12/14 23:03:09 done
105 » » » }
106 » » » return err
103 } 107 }
104 suffix = nil 108 suffix = nil
105 skip = -1 109 skip = -1
106 } 110 }
107 } 111 }
108 112
109 type cmd struct { 113 type cmd struct {
110 targ []byte 114 targ []byte
111 cb func(*gkvlite.Item) 115 cb func(*gkvlite.Item)
112 } 116 }
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 t.ch <- &cmd{targ, func(i *gkvlite.Item) { 211 t.ch <- &cmd{targ, func(i *gkvlite.Item) {
208 defer close(waiter) 212 defer close(waiter)
209 213
210 if i == nil { 214 if i == nil {
211 t.stop() 215 t.stop()
212 } 216 }
213 cb(i) 217 cb(i)
214 }} 218 }}
215 <-waiter 219 <-waiter
216 } 220 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698