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.

355 lines
7.3 KiB

  1. package db
  2. import (
  3. "bytes"
  4. "fmt"
  5. "sync"
  6. )
  7. // IteratePrefix is a convenience function for iterating over a key domain
  8. // restricted by prefix.
  9. func IteratePrefix(db DB, prefix []byte) Iterator {
  10. var start, end []byte
  11. if len(prefix) == 0 {
  12. start = nil
  13. end = nil
  14. } else {
  15. start = cp(prefix)
  16. end = cpIncr(prefix)
  17. }
  18. return db.Iterator(start, end)
  19. }
  20. /*
  21. TODO: Make test, maybe rename.
  22. // Like IteratePrefix but the iterator strips the prefix from the keys.
  23. func IteratePrefixStripped(db DB, prefix []byte) Iterator {
  24. start, end := ...
  25. return newPrefixIterator(prefix, start, end, IteratePrefix(db, prefix))
  26. }
  27. */
  28. //----------------------------------------
  29. // prefixDB
  30. type prefixDB struct {
  31. mtx sync.Mutex
  32. prefix []byte
  33. db DB
  34. }
  35. // NewPrefixDB lets you namespace multiple DBs within a single DB.
  36. func NewPrefixDB(db DB, prefix []byte) *prefixDB {
  37. return &prefixDB{
  38. prefix: prefix,
  39. db: db,
  40. }
  41. }
  42. // Implements atomicSetDeleter.
  43. func (pdb *prefixDB) Mutex() *sync.Mutex {
  44. return &(pdb.mtx)
  45. }
  46. // Implements DB.
  47. func (pdb *prefixDB) Get(key []byte) []byte {
  48. pdb.mtx.Lock()
  49. defer pdb.mtx.Unlock()
  50. pkey := pdb.prefixed(key)
  51. value := pdb.db.Get(pkey)
  52. return value
  53. }
  54. // Implements DB.
  55. func (pdb *prefixDB) Has(key []byte) bool {
  56. pdb.mtx.Lock()
  57. defer pdb.mtx.Unlock()
  58. return pdb.db.Has(pdb.prefixed(key))
  59. }
  60. // Implements DB.
  61. func (pdb *prefixDB) Set(key []byte, value []byte) {
  62. pdb.mtx.Lock()
  63. defer pdb.mtx.Unlock()
  64. pkey := pdb.prefixed(key)
  65. pdb.db.Set(pkey, value)
  66. }
  67. // Implements DB.
  68. func (pdb *prefixDB) SetSync(key []byte, value []byte) {
  69. pdb.mtx.Lock()
  70. defer pdb.mtx.Unlock()
  71. pdb.db.SetSync(pdb.prefixed(key), value)
  72. }
  73. // Implements DB.
  74. func (pdb *prefixDB) Delete(key []byte) {
  75. pdb.mtx.Lock()
  76. defer pdb.mtx.Unlock()
  77. pdb.db.Delete(pdb.prefixed(key))
  78. }
  79. // Implements DB.
  80. func (pdb *prefixDB) DeleteSync(key []byte) {
  81. pdb.mtx.Lock()
  82. defer pdb.mtx.Unlock()
  83. pdb.db.DeleteSync(pdb.prefixed(key))
  84. }
  85. // Implements DB.
  86. func (pdb *prefixDB) Iterator(start, end []byte) Iterator {
  87. pdb.mtx.Lock()
  88. defer pdb.mtx.Unlock()
  89. var pstart, pend []byte
  90. pstart = append(cp(pdb.prefix), start...)
  91. if end == nil {
  92. pend = cpIncr(pdb.prefix)
  93. } else {
  94. pend = append(cp(pdb.prefix), end...)
  95. }
  96. return newPrefixIterator(
  97. pdb.prefix,
  98. start,
  99. end,
  100. pdb.db.Iterator(
  101. pstart,
  102. pend,
  103. ),
  104. )
  105. }
  106. // Implements DB.
  107. func (pdb *prefixDB) ReverseIterator(start, end []byte) Iterator {
  108. pdb.mtx.Lock()
  109. defer pdb.mtx.Unlock()
  110. var pstart, pend []byte
  111. if start == nil {
  112. // This may cause the underlying iterator to start with
  113. // an item which doesn't start with prefix. We will skip
  114. // that item later in this function. See 'skipOne'.
  115. pstart = cpIncr(pdb.prefix)
  116. } else {
  117. pstart = append(cp(pdb.prefix), start...)
  118. }
  119. if end == nil {
  120. // This may cause the underlying iterator to end with an
  121. // item which doesn't start with prefix. The
  122. // prefixIterator will terminate iteration
  123. // automatically upon detecting this.
  124. pend = cpDecr(pdb.prefix)
  125. } else {
  126. pend = append(cp(pdb.prefix), end...)
  127. }
  128. ritr := pdb.db.ReverseIterator(pstart, pend)
  129. if start == nil {
  130. skipOne(ritr, cpIncr(pdb.prefix))
  131. }
  132. return newPrefixIterator(
  133. pdb.prefix,
  134. start,
  135. end,
  136. ritr,
  137. )
  138. }
  139. // Implements DB.
  140. // Panics if the underlying DB is not an
  141. // atomicSetDeleter.
  142. func (pdb *prefixDB) NewBatch() Batch {
  143. pdb.mtx.Lock()
  144. defer pdb.mtx.Unlock()
  145. return newPrefixBatch(pdb.prefix, pdb.db.NewBatch())
  146. }
  147. /* NOTE: Uncomment to use memBatch instead of prefixBatch
  148. // Implements atomicSetDeleter.
  149. func (pdb *prefixDB) SetNoLock(key []byte, value []byte) {
  150. pdb.db.(atomicSetDeleter).SetNoLock(pdb.prefixed(key), value)
  151. }
  152. // Implements atomicSetDeleter.
  153. func (pdb *prefixDB) SetNoLockSync(key []byte, value []byte) {
  154. pdb.db.(atomicSetDeleter).SetNoLockSync(pdb.prefixed(key), value)
  155. }
  156. // Implements atomicSetDeleter.
  157. func (pdb *prefixDB) DeleteNoLock(key []byte) {
  158. pdb.db.(atomicSetDeleter).DeleteNoLock(pdb.prefixed(key))
  159. }
  160. // Implements atomicSetDeleter.
  161. func (pdb *prefixDB) DeleteNoLockSync(key []byte) {
  162. pdb.db.(atomicSetDeleter).DeleteNoLockSync(pdb.prefixed(key))
  163. }
  164. */
  165. // Implements DB.
  166. func (pdb *prefixDB) Close() {
  167. pdb.mtx.Lock()
  168. defer pdb.mtx.Unlock()
  169. pdb.db.Close()
  170. }
  171. // Implements DB.
  172. func (pdb *prefixDB) Print() {
  173. fmt.Printf("prefix: %X\n", pdb.prefix)
  174. itr := pdb.Iterator(nil, nil)
  175. defer itr.Close()
  176. for ; itr.Valid(); itr.Next() {
  177. key := itr.Key()
  178. value := itr.Value()
  179. fmt.Printf("[%X]:\t[%X]\n", key, value)
  180. }
  181. }
  182. // Implements DB.
  183. func (pdb *prefixDB) Stats() map[string]string {
  184. stats := make(map[string]string)
  185. stats["prefixdb.prefix.string"] = string(pdb.prefix)
  186. stats["prefixdb.prefix.hex"] = fmt.Sprintf("%X", pdb.prefix)
  187. source := pdb.db.Stats()
  188. for key, value := range source {
  189. stats["prefixdb.source."+key] = value
  190. }
  191. return stats
  192. }
  193. func (pdb *prefixDB) prefixed(key []byte) []byte {
  194. return append(cp(pdb.prefix), key...)
  195. }
  196. //----------------------------------------
  197. // prefixBatch
  198. type prefixBatch struct {
  199. prefix []byte
  200. source Batch
  201. }
  202. func newPrefixBatch(prefix []byte, source Batch) prefixBatch {
  203. return prefixBatch{
  204. prefix: prefix,
  205. source: source,
  206. }
  207. }
  208. func (pb prefixBatch) Set(key, value []byte) {
  209. pkey := append(cp(pb.prefix), key...)
  210. pb.source.Set(pkey, value)
  211. }
  212. func (pb prefixBatch) Delete(key []byte) {
  213. pkey := append(cp(pb.prefix), key...)
  214. pb.source.Delete(pkey)
  215. }
  216. func (pb prefixBatch) Write() {
  217. pb.source.Write()
  218. }
  219. func (pb prefixBatch) WriteSync() {
  220. pb.source.WriteSync()
  221. }
  222. //----------------------------------------
  223. // prefixIterator
  224. // Strips prefix while iterating from Iterator.
  225. type prefixIterator struct {
  226. prefix []byte
  227. start []byte
  228. end []byte
  229. source Iterator
  230. valid bool
  231. }
  232. func newPrefixIterator(prefix, start, end []byte, source Iterator) prefixIterator {
  233. if !source.Valid() || !bytes.HasPrefix(source.Key(), prefix) {
  234. return prefixIterator{
  235. prefix: prefix,
  236. start: start,
  237. end: end,
  238. source: source,
  239. valid: false,
  240. }
  241. } else {
  242. return prefixIterator{
  243. prefix: prefix,
  244. start: start,
  245. end: end,
  246. source: source,
  247. valid: true,
  248. }
  249. }
  250. }
  251. func (itr prefixIterator) Domain() (start []byte, end []byte) {
  252. return itr.start, itr.end
  253. }
  254. func (itr prefixIterator) Valid() bool {
  255. return itr.valid && itr.source.Valid()
  256. }
  257. func (itr prefixIterator) Next() {
  258. if !itr.valid {
  259. panic("prefixIterator invalid, cannot call Next()")
  260. }
  261. itr.source.Next()
  262. if !itr.source.Valid() || !bytes.HasPrefix(itr.source.Key(), itr.prefix) {
  263. itr.source.Close()
  264. itr.valid = false
  265. return
  266. }
  267. }
  268. func (itr prefixIterator) Key() (key []byte) {
  269. if !itr.valid {
  270. panic("prefixIterator invalid, cannot call Key()")
  271. }
  272. return stripPrefix(itr.source.Key(), itr.prefix)
  273. }
  274. func (itr prefixIterator) Value() (value []byte) {
  275. if !itr.valid {
  276. panic("prefixIterator invalid, cannot call Value()")
  277. }
  278. return itr.source.Value()
  279. }
  280. func (itr prefixIterator) Close() {
  281. itr.source.Close()
  282. }
  283. //----------------------------------------
  284. func stripPrefix(key []byte, prefix []byte) (stripped []byte) {
  285. if len(key) < len(prefix) {
  286. panic("should not happen")
  287. }
  288. if !bytes.Equal(key[:len(prefix)], prefix) {
  289. panic("should not happne")
  290. }
  291. return key[len(prefix):]
  292. }
  293. // If the first iterator item is skipKey, then
  294. // skip it.
  295. func skipOne(itr Iterator, skipKey []byte) {
  296. if itr.Valid() {
  297. if bytes.Equal(itr.Key(), skipKey) {
  298. itr.Next()
  299. }
  300. }
  301. }