OSDN Git Service

new repo
[bytom/vapor.git] / vendor / github.com / syndtr / goleveldb / leveldb / iterator / indexed_iter.go
1 // Copyright (c) 2012, Suryandaru Triandana <syndtr@gmail.com>
2 // All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style license that can be
5 // found in the LICENSE file.
6
7 package iterator
8
9 import (
10         "github.com/syndtr/goleveldb/leveldb/errors"
11         "github.com/syndtr/goleveldb/leveldb/util"
12 )
13
14 // IteratorIndexer is the interface that wraps CommonIterator and basic Get
15 // method. IteratorIndexer provides index for indexed iterator.
16 type IteratorIndexer interface {
17         CommonIterator
18
19         // Get returns a new data iterator for the current position, or nil if
20         // done.
21         Get() Iterator
22 }
23
24 type indexedIterator struct {
25         util.BasicReleaser
26         index  IteratorIndexer
27         strict bool
28
29         data   Iterator
30         err    error
31         errf   func(err error)
32         closed bool
33 }
34
35 func (i *indexedIterator) setData() {
36         if i.data != nil {
37                 i.data.Release()
38         }
39         i.data = i.index.Get()
40 }
41
42 func (i *indexedIterator) clearData() {
43         if i.data != nil {
44                 i.data.Release()
45         }
46         i.data = nil
47 }
48
49 func (i *indexedIterator) indexErr() {
50         if err := i.index.Error(); err != nil {
51                 if i.errf != nil {
52                         i.errf(err)
53                 }
54                 i.err = err
55         }
56 }
57
58 func (i *indexedIterator) dataErr() bool {
59         if err := i.data.Error(); err != nil {
60                 if i.errf != nil {
61                         i.errf(err)
62                 }
63                 if i.strict || !errors.IsCorrupted(err) {
64                         i.err = err
65                         return true
66                 }
67         }
68         return false
69 }
70
71 func (i *indexedIterator) Valid() bool {
72         return i.data != nil && i.data.Valid()
73 }
74
75 func (i *indexedIterator) First() bool {
76         if i.err != nil {
77                 return false
78         } else if i.Released() {
79                 i.err = ErrIterReleased
80                 return false
81         }
82
83         if !i.index.First() {
84                 i.indexErr()
85                 i.clearData()
86                 return false
87         }
88         i.setData()
89         return i.Next()
90 }
91
92 func (i *indexedIterator) Last() bool {
93         if i.err != nil {
94                 return false
95         } else if i.Released() {
96                 i.err = ErrIterReleased
97                 return false
98         }
99
100         if !i.index.Last() {
101                 i.indexErr()
102                 i.clearData()
103                 return false
104         }
105         i.setData()
106         if !i.data.Last() {
107                 if i.dataErr() {
108                         return false
109                 }
110                 i.clearData()
111                 return i.Prev()
112         }
113         return true
114 }
115
116 func (i *indexedIterator) Seek(key []byte) bool {
117         if i.err != nil {
118                 return false
119         } else if i.Released() {
120                 i.err = ErrIterReleased
121                 return false
122         }
123
124         if !i.index.Seek(key) {
125                 i.indexErr()
126                 i.clearData()
127                 return false
128         }
129         i.setData()
130         if !i.data.Seek(key) {
131                 if i.dataErr() {
132                         return false
133                 }
134                 i.clearData()
135                 return i.Next()
136         }
137         return true
138 }
139
140 func (i *indexedIterator) Next() bool {
141         if i.err != nil {
142                 return false
143         } else if i.Released() {
144                 i.err = ErrIterReleased
145                 return false
146         }
147
148         switch {
149         case i.data != nil && !i.data.Next():
150                 if i.dataErr() {
151                         return false
152                 }
153                 i.clearData()
154                 fallthrough
155         case i.data == nil:
156                 if !i.index.Next() {
157                         i.indexErr()
158                         return false
159                 }
160                 i.setData()
161                 return i.Next()
162         }
163         return true
164 }
165
166 func (i *indexedIterator) Prev() bool {
167         if i.err != nil {
168                 return false
169         } else if i.Released() {
170                 i.err = ErrIterReleased
171                 return false
172         }
173
174         switch {
175         case i.data != nil && !i.data.Prev():
176                 if i.dataErr() {
177                         return false
178                 }
179                 i.clearData()
180                 fallthrough
181         case i.data == nil:
182                 if !i.index.Prev() {
183                         i.indexErr()
184                         return false
185                 }
186                 i.setData()
187                 if !i.data.Last() {
188                         if i.dataErr() {
189                                 return false
190                         }
191                         i.clearData()
192                         return i.Prev()
193                 }
194         }
195         return true
196 }
197
198 func (i *indexedIterator) Key() []byte {
199         if i.data == nil {
200                 return nil
201         }
202         return i.data.Key()
203 }
204
205 func (i *indexedIterator) Value() []byte {
206         if i.data == nil {
207                 return nil
208         }
209         return i.data.Value()
210 }
211
212 func (i *indexedIterator) Release() {
213         i.clearData()
214         i.index.Release()
215         i.BasicReleaser.Release()
216 }
217
218 func (i *indexedIterator) Error() error {
219         if i.err != nil {
220                 return i.err
221         }
222         if err := i.index.Error(); err != nil {
223                 return err
224         }
225         return nil
226 }
227
228 func (i *indexedIterator) SetErrorCallback(f func(err error)) {
229         i.errf = f
230 }
231
232 // NewIndexedIterator returns an 'indexed iterator'. An index is iterator
233 // that returns another iterator, a 'data iterator'. A 'data iterator' is the
234 // iterator that contains actual key/value pairs.
235 //
236 // If strict is true the any 'corruption errors' (i.e errors.IsCorrupted(err) == true)
237 // won't be ignored and will halt 'indexed iterator', otherwise the iterator will
238 // continue to the next 'data iterator'. Corruption on 'index iterator' will not be
239 // ignored and will halt the iterator.
240 func NewIndexedIterator(index IteratorIndexer, strict bool) Iterator {
241         return &indexedIterator{index: index, strict: strict}
242 }