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.

475 lines
10 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 memdb provides in-memory key/value database implementation.
  7. package memdb
  8. import (
  9. "math/rand"
  10. "sync"
  11. "github.com/syndtr/goleveldb/leveldb/comparer"
  12. "github.com/syndtr/goleveldb/leveldb/errors"
  13. "github.com/syndtr/goleveldb/leveldb/iterator"
  14. "github.com/syndtr/goleveldb/leveldb/util"
  15. )
  16. // Common errors.
  17. var (
  18. ErrNotFound = errors.ErrNotFound
  19. ErrIterReleased = errors.New("leveldb/memdb: iterator released")
  20. )
  21. const tMaxHeight = 12
  22. type dbIter struct {
  23. util.BasicReleaser
  24. p *DB
  25. slice *util.Range
  26. node int
  27. forward bool
  28. key, value []byte
  29. err error
  30. }
  31. func (i *dbIter) fill(checkStart, checkLimit bool) bool {
  32. if i.node != 0 {
  33. n := i.p.nodeData[i.node]
  34. m := n + i.p.nodeData[i.node+nKey]
  35. i.key = i.p.kvData[n:m]
  36. if i.slice != nil {
  37. switch {
  38. case checkLimit && i.slice.Limit != nil && i.p.cmp.Compare(i.key, i.slice.Limit) >= 0:
  39. fallthrough
  40. case checkStart && i.slice.Start != nil && i.p.cmp.Compare(i.key, i.slice.Start) < 0:
  41. i.node = 0
  42. goto bail
  43. }
  44. }
  45. i.value = i.p.kvData[m : m+i.p.nodeData[i.node+nVal]]
  46. return true
  47. }
  48. bail:
  49. i.key = nil
  50. i.value = nil
  51. return false
  52. }
  53. func (i *dbIter) Valid() bool {
  54. return i.node != 0
  55. }
  56. func (i *dbIter) First() bool {
  57. if i.Released() {
  58. i.err = ErrIterReleased
  59. return false
  60. }
  61. i.forward = true
  62. i.p.mu.RLock()
  63. defer i.p.mu.RUnlock()
  64. if i.slice != nil && i.slice.Start != nil {
  65. i.node, _ = i.p.findGE(i.slice.Start, false)
  66. } else {
  67. i.node = i.p.nodeData[nNext]
  68. }
  69. return i.fill(false, true)
  70. }
  71. func (i *dbIter) Last() bool {
  72. if i.Released() {
  73. i.err = ErrIterReleased
  74. return false
  75. }
  76. i.forward = false
  77. i.p.mu.RLock()
  78. defer i.p.mu.RUnlock()
  79. if i.slice != nil && i.slice.Limit != nil {
  80. i.node = i.p.findLT(i.slice.Limit)
  81. } else {
  82. i.node = i.p.findLast()
  83. }
  84. return i.fill(true, false)
  85. }
  86. func (i *dbIter) Seek(key []byte) bool {
  87. if i.Released() {
  88. i.err = ErrIterReleased
  89. return false
  90. }
  91. i.forward = true
  92. i.p.mu.RLock()
  93. defer i.p.mu.RUnlock()
  94. if i.slice != nil && i.slice.Start != nil && i.p.cmp.Compare(key, i.slice.Start) < 0 {
  95. key = i.slice.Start
  96. }
  97. i.node, _ = i.p.findGE(key, false)
  98. return i.fill(false, true)
  99. }
  100. func (i *dbIter) Next() bool {
  101. if i.Released() {
  102. i.err = ErrIterReleased
  103. return false
  104. }
  105. if i.node == 0 {
  106. if !i.forward {
  107. return i.First()
  108. }
  109. return false
  110. }
  111. i.forward = true
  112. i.p.mu.RLock()
  113. defer i.p.mu.RUnlock()
  114. i.node = i.p.nodeData[i.node+nNext]
  115. return i.fill(false, true)
  116. }
  117. func (i *dbIter) Prev() bool {
  118. if i.Released() {
  119. i.err = ErrIterReleased
  120. return false
  121. }
  122. if i.node == 0 {
  123. if i.forward {
  124. return i.Last()
  125. }
  126. return false
  127. }
  128. i.forward = false
  129. i.p.mu.RLock()
  130. defer i.p.mu.RUnlock()
  131. i.node = i.p.findLT(i.key)
  132. return i.fill(true, false)
  133. }
  134. func (i *dbIter) Key() []byte {
  135. return i.key
  136. }
  137. func (i *dbIter) Value() []byte {
  138. return i.value
  139. }
  140. func (i *dbIter) Error() error { return i.err }
  141. func (i *dbIter) Release() {
  142. if !i.Released() {
  143. i.p = nil
  144. i.node = 0
  145. i.key = nil
  146. i.value = nil
  147. i.BasicReleaser.Release()
  148. }
  149. }
  150. const (
  151. nKV = iota
  152. nKey
  153. nVal
  154. nHeight
  155. nNext
  156. )
  157. // DB is an in-memory key/value database.
  158. type DB struct {
  159. cmp comparer.BasicComparer
  160. rnd *rand.Rand
  161. mu sync.RWMutex
  162. kvData []byte
  163. // Node data:
  164. // [0] : KV offset
  165. // [1] : Key length
  166. // [2] : Value length
  167. // [3] : Height
  168. // [3..height] : Next nodes
  169. nodeData []int
  170. prevNode [tMaxHeight]int
  171. maxHeight int
  172. n int
  173. kvSize int
  174. }
  175. func (p *DB) randHeight() (h int) {
  176. const branching = 4
  177. h = 1
  178. for h < tMaxHeight && p.rnd.Int()%branching == 0 {
  179. h++
  180. }
  181. return
  182. }
  183. // Must hold RW-lock if prev == true, as it use shared prevNode slice.
  184. func (p *DB) findGE(key []byte, prev bool) (int, bool) {
  185. node := 0
  186. h := p.maxHeight - 1
  187. for {
  188. next := p.nodeData[node+nNext+h]
  189. cmp := 1
  190. if next != 0 {
  191. o := p.nodeData[next]
  192. cmp = p.cmp.Compare(p.kvData[o:o+p.nodeData[next+nKey]], key)
  193. }
  194. if cmp < 0 {
  195. // Keep searching in this list
  196. node = next
  197. } else {
  198. if prev {
  199. p.prevNode[h] = node
  200. } else if cmp == 0 {
  201. return next, true
  202. }
  203. if h == 0 {
  204. return next, cmp == 0
  205. }
  206. h--
  207. }
  208. }
  209. }
  210. func (p *DB) findLT(key []byte) int {
  211. node := 0
  212. h := p.maxHeight - 1
  213. for {
  214. next := p.nodeData[node+nNext+h]
  215. o := p.nodeData[next]
  216. if next == 0 || p.cmp.Compare(p.kvData[o:o+p.nodeData[next+nKey]], key) >= 0 {
  217. if h == 0 {
  218. break
  219. }
  220. h--
  221. } else {
  222. node = next
  223. }
  224. }
  225. return node
  226. }
  227. func (p *DB) findLast() int {
  228. node := 0
  229. h := p.maxHeight - 1
  230. for {
  231. next := p.nodeData[node+nNext+h]
  232. if next == 0 {
  233. if h == 0 {
  234. break
  235. }
  236. h--
  237. } else {
  238. node = next
  239. }
  240. }
  241. return node
  242. }
  243. // Put sets the value for the given key. It overwrites any previous value
  244. // for that key; a DB is not a multi-map.
  245. //
  246. // It is safe to modify the contents of the arguments after Put returns.
  247. func (p *DB) Put(key []byte, value []byte) error {
  248. p.mu.Lock()
  249. defer p.mu.Unlock()
  250. if node, exact := p.findGE(key, true); exact {
  251. kvOffset := len(p.kvData)
  252. p.kvData = append(p.kvData, key...)
  253. p.kvData = append(p.kvData, value...)
  254. p.nodeData[node] = kvOffset
  255. m := p.nodeData[node+nVal]
  256. p.nodeData[node+nVal] = len(value)
  257. p.kvSize += len(value) - m
  258. return nil
  259. }
  260. h := p.randHeight()
  261. if h > p.maxHeight {
  262. for i := p.maxHeight; i < h; i++ {
  263. p.prevNode[i] = 0
  264. }
  265. p.maxHeight = h
  266. }
  267. kvOffset := len(p.kvData)
  268. p.kvData = append(p.kvData, key...)
  269. p.kvData = append(p.kvData, value...)
  270. // Node
  271. node := len(p.nodeData)
  272. p.nodeData = append(p.nodeData, kvOffset, len(key), len(value), h)
  273. for i, n := range p.prevNode[:h] {
  274. m := n + nNext + i
  275. p.nodeData = append(p.nodeData, p.nodeData[m])
  276. p.nodeData[m] = node
  277. }
  278. p.kvSize += len(key) + len(value)
  279. p.n++
  280. return nil
  281. }
  282. // Delete deletes the value for the given key. It returns ErrNotFound if
  283. // the DB does not contain the key.
  284. //
  285. // It is safe to modify the contents of the arguments after Delete returns.
  286. func (p *DB) Delete(key []byte) error {
  287. p.mu.Lock()
  288. defer p.mu.Unlock()
  289. node, exact := p.findGE(key, true)
  290. if !exact {
  291. return ErrNotFound
  292. }
  293. h := p.nodeData[node+nHeight]
  294. for i, n := range p.prevNode[:h] {
  295. m := n + nNext + i
  296. p.nodeData[m] = p.nodeData[p.nodeData[m]+nNext+i]
  297. }
  298. p.kvSize -= p.nodeData[node+nKey] + p.nodeData[node+nVal]
  299. p.n--
  300. return nil
  301. }
  302. // Contains returns true if the given key are in the DB.
  303. //
  304. // It is safe to modify the contents of the arguments after Contains returns.
  305. func (p *DB) Contains(key []byte) bool {
  306. p.mu.RLock()
  307. _, exact := p.findGE(key, false)
  308. p.mu.RUnlock()
  309. return exact
  310. }
  311. // Get gets the value for the given key. It returns error.ErrNotFound if the
  312. // DB does not contain the key.
  313. //
  314. // The caller should not modify the contents of the returned slice, but
  315. // it is safe to modify the contents of the argument after Get returns.
  316. func (p *DB) Get(key []byte) (value []byte, err error) {
  317. p.mu.RLock()
  318. if node, exact := p.findGE(key, false); exact {
  319. o := p.nodeData[node] + p.nodeData[node+nKey]
  320. value = p.kvData[o : o+p.nodeData[node+nVal]]
  321. } else {
  322. err = ErrNotFound
  323. }
  324. p.mu.RUnlock()
  325. return
  326. }
  327. // Find finds key/value pair whose key is greater than or equal to the
  328. // given key. It returns ErrNotFound if the table doesn't contain
  329. // such pair.
  330. //
  331. // The caller should not modify the contents of the returned slice, but
  332. // it is safe to modify the contents of the argument after Find returns.
  333. func (p *DB) Find(key []byte) (rkey, value []byte, err error) {
  334. p.mu.RLock()
  335. if node, _ := p.findGE(key, false); node != 0 {
  336. n := p.nodeData[node]
  337. m := n + p.nodeData[node+nKey]
  338. rkey = p.kvData[n:m]
  339. value = p.kvData[m : m+p.nodeData[node+nVal]]
  340. } else {
  341. err = ErrNotFound
  342. }
  343. p.mu.RUnlock()
  344. return
  345. }
  346. // NewIterator returns an iterator of the DB.
  347. // The returned iterator is not safe for concurrent use, but it is safe to use
  348. // multiple iterators concurrently, with each in a dedicated goroutine.
  349. // It is also safe to use an iterator concurrently with modifying its
  350. // underlying DB. However, the resultant key/value pairs are not guaranteed
  351. // to be a consistent snapshot of the DB at a particular point in time.
  352. //
  353. // Slice allows slicing the iterator to only contains keys in the given
  354. // range. A nil Range.Start is treated as a key before all keys in the
  355. // DB. And a nil Range.Limit is treated as a key after all keys in
  356. // the DB.
  357. //
  358. // The iterator must be released after use, by calling Release method.
  359. //
  360. // Also read Iterator documentation of the leveldb/iterator package.
  361. func (p *DB) NewIterator(slice *util.Range) iterator.Iterator {
  362. return &dbIter{p: p, slice: slice}
  363. }
  364. // Capacity returns keys/values buffer capacity.
  365. func (p *DB) Capacity() int {
  366. p.mu.RLock()
  367. defer p.mu.RUnlock()
  368. return cap(p.kvData)
  369. }
  370. // Size returns sum of keys and values length. Note that deleted
  371. // key/value will not be accounted for, but it will still consume
  372. // the buffer, since the buffer is append only.
  373. func (p *DB) Size() int {
  374. p.mu.RLock()
  375. defer p.mu.RUnlock()
  376. return p.kvSize
  377. }
  378. // Free returns keys/values free buffer before need to grow.
  379. func (p *DB) Free() int {
  380. p.mu.RLock()
  381. defer p.mu.RUnlock()
  382. return cap(p.kvData) - len(p.kvData)
  383. }
  384. // Len returns the number of entries in the DB.
  385. func (p *DB) Len() int {
  386. p.mu.RLock()
  387. defer p.mu.RUnlock()
  388. return p.n
  389. }
  390. // Reset resets the DB to initial empty state. Allows reuse the buffer.
  391. func (p *DB) Reset() {
  392. p.mu.Lock()
  393. p.rnd = rand.New(rand.NewSource(0xdeadbeef))
  394. p.maxHeight = 1
  395. p.n = 0
  396. p.kvSize = 0
  397. p.kvData = p.kvData[:0]
  398. p.nodeData = p.nodeData[:nNext+tMaxHeight]
  399. p.nodeData[nKV] = 0
  400. p.nodeData[nKey] = 0
  401. p.nodeData[nVal] = 0
  402. p.nodeData[nHeight] = tMaxHeight
  403. for n := 0; n < tMaxHeight; n++ {
  404. p.nodeData[nNext+n] = 0
  405. p.prevNode[n] = 0
  406. }
  407. p.mu.Unlock()
  408. }
  409. // New creates a new initialized in-memory key/value DB. The capacity
  410. // is the initial key/value buffer capacity. The capacity is advisory,
  411. // not enforced.
  412. //
  413. // This DB is append-only, deleting an entry would remove entry node but not
  414. // reclaim KV buffer.
  415. //
  416. // The returned DB instance is safe for concurrent use.
  417. func New(cmp comparer.BasicComparer, capacity int) *DB {
  418. p := &DB{
  419. cmp: cmp,
  420. rnd: rand.New(rand.NewSource(0xdeadbeef)),
  421. maxHeight: 1,
  422. kvData: make([]byte, 0, capacity),
  423. nodeData: make([]int, 4+tMaxHeight),
  424. }
  425. p.nodeData[nHeight] = tMaxHeight
  426. return p
  427. }