You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

360 lines
6.8 KiB

  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. package leveldb
  7. import (
  8. "errors"
  9. "math/rand"
  10. "runtime"
  11. "sync"
  12. "sync/atomic"
  13. "github.com/syndtr/goleveldb/leveldb/iterator"
  14. "github.com/syndtr/goleveldb/leveldb/opt"
  15. "github.com/syndtr/goleveldb/leveldb/util"
  16. )
  17. var (
  18. errInvalidInternalKey = errors.New("leveldb: Iterator: invalid internal key")
  19. )
  20. type memdbReleaser struct {
  21. once sync.Once
  22. m *memDB
  23. }
  24. func (mr *memdbReleaser) Release() {
  25. mr.once.Do(func() {
  26. mr.m.decref()
  27. })
  28. }
  29. func (db *DB) newRawIterator(auxm *memDB, auxt tFiles, slice *util.Range, ro *opt.ReadOptions) iterator.Iterator {
  30. strict := opt.GetStrict(db.s.o.Options, ro, opt.StrictReader)
  31. em, fm := db.getMems()
  32. v := db.s.version()
  33. tableIts := v.getIterators(slice, ro)
  34. n := len(tableIts) + len(auxt) + 3
  35. its := make([]iterator.Iterator, 0, n)
  36. if auxm != nil {
  37. ami := auxm.NewIterator(slice)
  38. ami.SetReleaser(&memdbReleaser{m: auxm})
  39. its = append(its, ami)
  40. }
  41. for _, t := range auxt {
  42. its = append(its, v.s.tops.newIterator(t, slice, ro))
  43. }
  44. emi := em.NewIterator(slice)
  45. emi.SetReleaser(&memdbReleaser{m: em})
  46. its = append(its, emi)
  47. if fm != nil {
  48. fmi := fm.NewIterator(slice)
  49. fmi.SetReleaser(&memdbReleaser{m: fm})
  50. its = append(its, fmi)
  51. }
  52. its = append(its, tableIts...)
  53. mi := iterator.NewMergedIterator(its, db.s.icmp, strict)
  54. mi.SetReleaser(&versionReleaser{v: v})
  55. return mi
  56. }
  57. func (db *DB) newIterator(auxm *memDB, auxt tFiles, seq uint64, slice *util.Range, ro *opt.ReadOptions) *dbIter {
  58. var islice *util.Range
  59. if slice != nil {
  60. islice = &util.Range{}
  61. if slice.Start != nil {
  62. islice.Start = makeInternalKey(nil, slice.Start, keyMaxSeq, keyTypeSeek)
  63. }
  64. if slice.Limit != nil {
  65. islice.Limit = makeInternalKey(nil, slice.Limit, keyMaxSeq, keyTypeSeek)
  66. }
  67. }
  68. rawIter := db.newRawIterator(auxm, auxt, islice, ro)
  69. iter := &dbIter{
  70. db: db,
  71. icmp: db.s.icmp,
  72. iter: rawIter,
  73. seq: seq,
  74. strict: opt.GetStrict(db.s.o.Options, ro, opt.StrictReader),
  75. key: make([]byte, 0),
  76. value: make([]byte, 0),
  77. }
  78. atomic.AddInt32(&db.aliveIters, 1)
  79. runtime.SetFinalizer(iter, (*dbIter).Release)
  80. return iter
  81. }
  82. func (db *DB) iterSamplingRate() int {
  83. return rand.Intn(2 * db.s.o.GetIteratorSamplingRate())
  84. }
  85. type dir int
  86. const (
  87. dirReleased dir = iota - 1
  88. dirSOI
  89. dirEOI
  90. dirBackward
  91. dirForward
  92. )
  93. // dbIter represent an interator states over a database session.
  94. type dbIter struct {
  95. db *DB
  96. icmp *iComparer
  97. iter iterator.Iterator
  98. seq uint64
  99. strict bool
  100. smaplingGap int
  101. dir dir
  102. key []byte
  103. value []byte
  104. err error
  105. releaser util.Releaser
  106. }
  107. func (i *dbIter) sampleSeek() {
  108. ikey := i.iter.Key()
  109. i.smaplingGap -= len(ikey) + len(i.iter.Value())
  110. for i.smaplingGap < 0 {
  111. i.smaplingGap += i.db.iterSamplingRate()
  112. i.db.sampleSeek(ikey)
  113. }
  114. }
  115. func (i *dbIter) setErr(err error) {
  116. i.err = err
  117. i.key = nil
  118. i.value = nil
  119. }
  120. func (i *dbIter) iterErr() {
  121. if err := i.iter.Error(); err != nil {
  122. i.setErr(err)
  123. }
  124. }
  125. func (i *dbIter) Valid() bool {
  126. return i.err == nil && i.dir > dirEOI
  127. }
  128. func (i *dbIter) First() bool {
  129. if i.err != nil {
  130. return false
  131. } else if i.dir == dirReleased {
  132. i.err = ErrIterReleased
  133. return false
  134. }
  135. if i.iter.First() {
  136. i.dir = dirSOI
  137. return i.next()
  138. }
  139. i.dir = dirEOI
  140. i.iterErr()
  141. return false
  142. }
  143. func (i *dbIter) Last() bool {
  144. if i.err != nil {
  145. return false
  146. } else if i.dir == dirReleased {
  147. i.err = ErrIterReleased
  148. return false
  149. }
  150. if i.iter.Last() {
  151. return i.prev()
  152. }
  153. i.dir = dirSOI
  154. i.iterErr()
  155. return false
  156. }
  157. func (i *dbIter) Seek(key []byte) bool {
  158. if i.err != nil {
  159. return false
  160. } else if i.dir == dirReleased {
  161. i.err = ErrIterReleased
  162. return false
  163. }
  164. ikey := makeInternalKey(nil, key, i.seq, keyTypeSeek)
  165. if i.iter.Seek(ikey) {
  166. i.dir = dirSOI
  167. return i.next()
  168. }
  169. i.dir = dirEOI
  170. i.iterErr()
  171. return false
  172. }
  173. func (i *dbIter) next() bool {
  174. for {
  175. if ukey, seq, kt, kerr := parseInternalKey(i.iter.Key()); kerr == nil {
  176. i.sampleSeek()
  177. if seq <= i.seq {
  178. switch kt {
  179. case keyTypeDel:
  180. // Skip deleted key.
  181. i.key = append(i.key[:0], ukey...)
  182. i.dir = dirForward
  183. case keyTypeVal:
  184. if i.dir == dirSOI || i.icmp.uCompare(ukey, i.key) > 0 {
  185. i.key = append(i.key[:0], ukey...)
  186. i.value = append(i.value[:0], i.iter.Value()...)
  187. i.dir = dirForward
  188. return true
  189. }
  190. }
  191. }
  192. } else if i.strict {
  193. i.setErr(kerr)
  194. break
  195. }
  196. if !i.iter.Next() {
  197. i.dir = dirEOI
  198. i.iterErr()
  199. break
  200. }
  201. }
  202. return false
  203. }
  204. func (i *dbIter) Next() bool {
  205. if i.dir == dirEOI || i.err != nil {
  206. return false
  207. } else if i.dir == dirReleased {
  208. i.err = ErrIterReleased
  209. return false
  210. }
  211. if !i.iter.Next() || (i.dir == dirBackward && !i.iter.Next()) {
  212. i.dir = dirEOI
  213. i.iterErr()
  214. return false
  215. }
  216. return i.next()
  217. }
  218. func (i *dbIter) prev() bool {
  219. i.dir = dirBackward
  220. del := true
  221. if i.iter.Valid() {
  222. for {
  223. if ukey, seq, kt, kerr := parseInternalKey(i.iter.Key()); kerr == nil {
  224. i.sampleSeek()
  225. if seq <= i.seq {
  226. if !del && i.icmp.uCompare(ukey, i.key) < 0 {
  227. return true
  228. }
  229. del = (kt == keyTypeDel)
  230. if !del {
  231. i.key = append(i.key[:0], ukey...)
  232. i.value = append(i.value[:0], i.iter.Value()...)
  233. }
  234. }
  235. } else if i.strict {
  236. i.setErr(kerr)
  237. return false
  238. }
  239. if !i.iter.Prev() {
  240. break
  241. }
  242. }
  243. }
  244. if del {
  245. i.dir = dirSOI
  246. i.iterErr()
  247. return false
  248. }
  249. return true
  250. }
  251. func (i *dbIter) Prev() bool {
  252. if i.dir == dirSOI || i.err != nil {
  253. return false
  254. } else if i.dir == dirReleased {
  255. i.err = ErrIterReleased
  256. return false
  257. }
  258. switch i.dir {
  259. case dirEOI:
  260. return i.Last()
  261. case dirForward:
  262. for i.iter.Prev() {
  263. if ukey, _, _, kerr := parseInternalKey(i.iter.Key()); kerr == nil {
  264. i.sampleSeek()
  265. if i.icmp.uCompare(ukey, i.key) < 0 {
  266. goto cont
  267. }
  268. } else if i.strict {
  269. i.setErr(kerr)
  270. return false
  271. }
  272. }
  273. i.dir = dirSOI
  274. i.iterErr()
  275. return false
  276. }
  277. cont:
  278. return i.prev()
  279. }
  280. func (i *dbIter) Key() []byte {
  281. if i.err != nil || i.dir <= dirEOI {
  282. return nil
  283. }
  284. return i.key
  285. }
  286. func (i *dbIter) Value() []byte {
  287. if i.err != nil || i.dir <= dirEOI {
  288. return nil
  289. }
  290. return i.value
  291. }
  292. func (i *dbIter) Release() {
  293. if i.dir != dirReleased {
  294. // Clear the finalizer.
  295. runtime.SetFinalizer(i, nil)
  296. if i.releaser != nil {
  297. i.releaser.Release()
  298. i.releaser = nil
  299. }
  300. i.dir = dirReleased
  301. i.key = nil
  302. i.value = nil
  303. i.iter.Release()
  304. i.iter = nil
  305. atomic.AddInt32(&i.db.aliveIters, -1)
  306. i.db = nil
  307. }
  308. }
  309. func (i *dbIter) SetReleaser(releaser util.Releaser) {
  310. if i.dir == dirReleased {
  311. panic(util.ErrReleased)
  312. }
  313. if i.releaser != nil && releaser != nil {
  314. panic(util.ErrHasReleaser)
  315. }
  316. i.releaser = releaser
  317. }
  318. func (i *dbIter) Error() error {
  319. return i.err
  320. }