github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/syndtr/goleveldb/leveldb/iterator/indexed_iter.go (about) 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/insionng/yougam/libraries/syndtr/goleveldb/leveldb/errors" 11 "github.com/insionng/yougam/libraries/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 }