github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/syndtr/goleveldb/leveldb/iterator/array_iter.go (about) 1 // Copyright (c) 2014, 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/util" 11 ) 12 13 // BasicArray is the interface that wraps basic Len and Search method. 14 type BasicArray interface { 15 // Len returns length of the array. 16 Len() int 17 18 // Search finds smallest index that point to a key that is greater 19 // than or equal to the given key. 20 Search(key []byte) int 21 } 22 23 // Array is the interface that wraps BasicArray and basic Index method. 24 type Array interface { 25 BasicArray 26 27 // Index returns key/value pair with index of i. 28 Index(i int) (key, value []byte) 29 } 30 31 // Array is the interface that wraps BasicArray and basic Get method. 32 type ArrayIndexer interface { 33 BasicArray 34 35 // Get returns a new data iterator with index of i. 36 Get(i int) Iterator 37 } 38 39 type basicArrayIterator struct { 40 util.BasicReleaser 41 array BasicArray 42 pos int 43 err error 44 } 45 46 func (i *basicArrayIterator) Valid() bool { 47 return i.pos >= 0 && i.pos < i.array.Len() && !i.Released() 48 } 49 50 func (i *basicArrayIterator) First() bool { 51 if i.Released() { 52 i.err = ErrIterReleased 53 return false 54 } 55 56 if i.array.Len() == 0 { 57 i.pos = -1 58 return false 59 } 60 i.pos = 0 61 return true 62 } 63 64 func (i *basicArrayIterator) Last() bool { 65 if i.Released() { 66 i.err = ErrIterReleased 67 return false 68 } 69 70 n := i.array.Len() 71 if n == 0 { 72 i.pos = 0 73 return false 74 } 75 i.pos = n - 1 76 return true 77 } 78 79 func (i *basicArrayIterator) Seek(key []byte) bool { 80 if i.Released() { 81 i.err = ErrIterReleased 82 return false 83 } 84 85 n := i.array.Len() 86 if n == 0 { 87 i.pos = 0 88 return false 89 } 90 i.pos = i.array.Search(key) 91 if i.pos >= n { 92 return false 93 } 94 return true 95 } 96 97 func (i *basicArrayIterator) Next() bool { 98 if i.Released() { 99 i.err = ErrIterReleased 100 return false 101 } 102 103 i.pos++ 104 if n := i.array.Len(); i.pos >= n { 105 i.pos = n 106 return false 107 } 108 return true 109 } 110 111 func (i *basicArrayIterator) Prev() bool { 112 if i.Released() { 113 i.err = ErrIterReleased 114 return false 115 } 116 117 i.pos-- 118 if i.pos < 0 { 119 i.pos = -1 120 return false 121 } 122 return true 123 } 124 125 func (i *basicArrayIterator) Error() error { return i.err } 126 127 type arrayIterator struct { 128 basicArrayIterator 129 array Array 130 pos int 131 key, value []byte 132 } 133 134 func (i *arrayIterator) updateKV() { 135 if i.pos == i.basicArrayIterator.pos { 136 return 137 } 138 i.pos = i.basicArrayIterator.pos 139 if i.Valid() { 140 i.key, i.value = i.array.Index(i.pos) 141 } else { 142 i.key = nil 143 i.value = nil 144 } 145 } 146 147 func (i *arrayIterator) Key() []byte { 148 i.updateKV() 149 return i.key 150 } 151 152 func (i *arrayIterator) Value() []byte { 153 i.updateKV() 154 return i.value 155 } 156 157 type arrayIteratorIndexer struct { 158 basicArrayIterator 159 array ArrayIndexer 160 } 161 162 func (i *arrayIteratorIndexer) Get() Iterator { 163 if i.Valid() { 164 return i.array.Get(i.basicArrayIterator.pos) 165 } 166 return nil 167 } 168 169 // NewArrayIterator returns an iterator from the given array. 170 func NewArrayIterator(array Array) Iterator { 171 return &arrayIterator{ 172 basicArrayIterator: basicArrayIterator{array: array, pos: -1}, 173 array: array, 174 pos: -1, 175 } 176 } 177 178 // NewArrayIndexer returns an index iterator from the given array. 179 func NewArrayIndexer(array ArrayIndexer) IteratorIndexer { 180 return &arrayIteratorIndexer{ 181 basicArrayIterator: basicArrayIterator{array: array, pos: -1}, 182 array: array, 183 } 184 }