11package com .scalableminds .fossildb .db
22
3+ import org .rocksdb .RocksIterator
4+
35import scala .annotation .tailrec
46import scala .util .Try
57
@@ -56,7 +58,7 @@ class VersionFilterIterator(it: RocksDBIterator, version: Option[Long]) extends
5658
5759}
5860
59- class KeyOnlyIterator [T ](underlying : RocksDBStore , startAfterKey : Option [String ]) extends Iterator [String ] {
61+ class KeyOnlyIterator [T ](rocksIt : RocksIterator , startAfterKey : Option [String ]) extends Iterator [String ] {
6062
6163 /*
6264 Note that seek in the underlying iterators either hits precisely or goes to the
@@ -72,13 +74,13 @@ class KeyOnlyIterator[T](underlying: RocksDBStore, startAfterKey: Option[String]
7274 }
7375
7476 override def hasNext : Boolean = {
75- val it = underlying .scanKeysOnly(compositeKeyFor(currentKey), None )
77+ val it = RocksDBStore .scanKeysOnly(rocksIt, compositeKeyFor(currentKey), None )
7678 if (it.hasNext && currentKey.isDefined && currentKey.contains(VersionedKey (it.peek).get.key)) it.next()
7779 it.hasNext
7880 }
7981
8082 override def next (): String = {
81- val it = underlying .scanKeysOnly(compositeKeyFor(currentKey), None )
83+ val it = RocksDBStore .scanKeysOnly(rocksIt, compositeKeyFor(currentKey), None )
8284 if (it.hasNext && currentKey.isDefined && currentKey.contains(VersionedKey (it.peek).get.key)) it.next()
8385 val nextKey = VersionedKey (it.next()).get.key
8486 currentKey = Some (nextKey)
@@ -90,10 +92,12 @@ class KeyOnlyIterator[T](underlying: RocksDBStore, startAfterKey: Option[String]
9092
9193class VersionedKeyValueStore (underlying : RocksDBStore ) {
9294
93- def get (key : String , version : Option [Long ] = None ): Option [VersionedKeyValuePair [Array [Byte ]]] =
94- scanVersionValuePairs(key, version).nextOption()
95+ def withRawRocksIterator [T ](block : RocksIterator => T ): T = underlying.withRawRocksIterator(block)
96+
97+ def get (rocksIt : RocksIterator , key : String , version : Option [Long ] = None ): Option [VersionedKeyValuePair [Array [Byte ]]] =
98+ scanVersionValuePairs(rocksIt, key, version).nextOption()
9599
96- def getMultipleVersions (key : String , oldestVersion : Option [Long ] = None , newestVersion : Option [Long ] = None ): (List [Array [Byte ]], List [Long ]) = {
100+ def getMultipleVersions (rocksIt : RocksIterator , key : String , oldestVersion : Option [Long ] = None , newestVersion : Option [Long ] = None ): (List [Array [Byte ]], List [Long ]) = {
97101
98102 @ tailrec
99103 def toListIter (versionIterator : Iterator [VersionedKeyValuePair [Array [Byte ]]],
@@ -106,31 +110,31 @@ class VersionedKeyValueStore(underlying: RocksDBStore) {
106110 }
107111 }
108112
109- val iterator = scanVersionValuePairs(key, newestVersion)
113+ val iterator = scanVersionValuePairs(rocksIt, key, newestVersion)
110114 val (versions, keys) = toListIter(iterator, List (), List ())
111115 (versions.reverse, keys.reverse)
112116 }
113117
114- private def scanVersionValuePairs (key : String , version : Option [Long ] = None ): Iterator [VersionedKeyValuePair [Array [Byte ]]] = {
118+ private def scanVersionValuePairs (rocksIt : RocksIterator , key : String , version : Option [Long ] = None ): Iterator [VersionedKeyValuePair [Array [Byte ]]] = {
115119 requireValidKey(key)
116120 val prefix = s " $key${VersionedKey .versionSeparator}"
117- underlying .scan(version.map(VersionedKey (key, _).toString).getOrElse(prefix), Some (prefix)).flatMap { pair =>
121+ RocksDBStore .scan(rocksIt, version.map(VersionedKey (key, _).toString).getOrElse(prefix), Some (prefix)).flatMap { pair =>
118122 VersionedKey (pair.key).map(VersionedKeyValuePair (_, pair.value))
119123 }
120124 }
121125
122- private def scanVersionsOnly (key : String , version : Option [Long ] = None ): Iterator [VersionedKey ] = {
126+ private def scanVersionsOnly (rocksIt : RocksIterator , key : String , version : Option [Long ] = None ): Iterator [VersionedKey ] = {
123127 requireValidKey(key)
124128 val prefix = s " $key${VersionedKey .versionSeparator}"
125- underlying .scanKeysOnly(version.map(VersionedKey (key, _).toString).getOrElse(prefix), Some (prefix)).flatMap { key =>
129+ RocksDBStore .scanKeysOnly(rocksIt, version.map(VersionedKey (key, _).toString).getOrElse(prefix), Some (prefix)).flatMap { key =>
126130 VersionedKey (key)
127131 }
128132 }
129133
130- def getMultipleKeys (startAfterKey : Option [String ], prefix : Option [String ] = None , version : Option [Long ] = None , limit : Option [Int ]): (Seq [String ], Seq [Array [Byte ]], Seq [Long ]) = {
134+ def getMultipleKeys (rocksIt : RocksIterator , startAfterKey : Option [String ], prefix : Option [String ] = None , version : Option [Long ] = None , limit : Option [Int ]): (Seq [String ], Seq [Array [Byte ]], Seq [Long ]) = {
131135 startAfterKey.foreach(requireValidKey)
132136 prefix.foreach{ p => requireValidKey(p)}
133- val iterator : VersionFilterIterator = scanKeys(startAfterKey, prefix, version)
137+ val iterator : VersionFilterIterator = scanKeys(rocksIt, startAfterKey, prefix, version)
134138
135139 /*
136140 Note that seek in the underlying iterators either hits precisely or goes to the
@@ -155,12 +159,12 @@ class VersionedKeyValueStore(underlying: RocksDBStore) {
155159 (keys, values, versions)
156160 }
157161
158- private def scanKeys (startAfterKey : Option [String ], prefix : Option [String ] = None , version : Option [Long ] = None ): VersionFilterIterator = {
162+ private def scanKeys (rocksIt : RocksIterator , startAfterKey : Option [String ], prefix : Option [String ] = None , version : Option [Long ] = None ): VersionFilterIterator = {
159163 val fullKey = startAfterKey.map(key => s " $key${VersionedKey .versionSeparator}" ).orElse(prefix).getOrElse(" " )
160- new VersionFilterIterator (underlying .scan(fullKey, prefix), version)
164+ new VersionFilterIterator (RocksDBStore .scan(rocksIt, fullKey, prefix), version)
161165 }
162166
163- def deleteMultipleVersions (key : String , oldestVersion : Option [Long ] = None , newestVersion : Option [Long ] = None ): Unit = {
167+ def deleteMultipleVersions (rocksIt : RocksIterator , key : String , oldestVersion : Option [Long ] = None , newestVersion : Option [Long ] = None ): Unit = {
164168 @ tailrec
165169 def deleteIter (versionIterator : Iterator [VersionedKey ]): Unit = {
166170 if (versionIterator.hasNext) {
@@ -172,7 +176,7 @@ class VersionedKeyValueStore(underlying: RocksDBStore) {
172176 }
173177 }
174178
175- val versionsIterator = scanVersionsOnly(key, newestVersion)
179+ val versionsIterator = scanVersionsOnly(rocksIt, key, newestVersion)
176180 deleteIter(versionsIterator)
177181 }
178182
@@ -186,13 +190,13 @@ class VersionedKeyValueStore(underlying: RocksDBStore) {
186190 underlying.delete(VersionedKey (key, version).toString)
187191 }
188192
189- def listKeys (limit : Option [Int ], startAfterKey : Option [String ]): Seq [String ] = {
190- val iterator = new KeyOnlyIterator (underlying , startAfterKey)
193+ def listKeys (rocksIt : RocksIterator , limit : Option [Int ], startAfterKey : Option [String ]): Seq [String ] = {
194+ val iterator = new KeyOnlyIterator (rocksIt , startAfterKey)
191195 iterator.take(limit.getOrElse(Int .MaxValue )).toSeq
192196 }
193197
194- def listVersions (key : String , limit : Option [Int ], offset : Option [Int ]): Seq [Long ] = {
195- val iterator = scanVersionsOnly(key)
198+ def listVersions (rocksIt : RocksIterator , key : String , limit : Option [Int ], offset : Option [Int ]): Seq [Long ] = {
199+ val iterator = scanVersionsOnly(rocksIt, key)
196200 iterator.map(_.version).drop(offset.getOrElse(0 )).take(limit.getOrElse(Int .MaxValue )).toSeq
197201 }
198202
0 commit comments