Deep copy semantics for LRU cache
why: follows standard nim semantics details: changed Table to TableRef in previous patch which was the wrong choice (see andri's comment.)
This commit is contained in:
parent
7b72109afa
commit
e5947f4db6
|
@ -18,6 +18,9 @@
|
||||||
## (so long as the table does not degrade into one-bucket linear mode, or
|
## (so long as the table does not degrade into one-bucket linear mode, or
|
||||||
## some bucket-adjustment algorithm takes over.)
|
## some bucket-adjustment algorithm takes over.)
|
||||||
##
|
##
|
||||||
|
## For consistency with every other data type in Nim these have value
|
||||||
|
## semantics, this means that `=` performs a deep copy of the LRU cache.
|
||||||
|
##
|
||||||
|
|
||||||
import
|
import
|
||||||
math,
|
math,
|
||||||
|
@ -50,7 +53,7 @@ type
|
||||||
LruData[K,V] = object
|
LruData[K,V] = object
|
||||||
maxItems: int ## Max number of entries
|
maxItems: int ## Max number of entries
|
||||||
first, last: K ## Doubly linked item list queue
|
first, last: K ## Doubly linked item list queue
|
||||||
tab: TableRef[K,LruItem[K,V]] ## (`key`,encapsulated(`value`)) data table
|
tab: Table[K,LruItem[K,V]] ## (`key`,encapsulated(`value`)) data table
|
||||||
|
|
||||||
LruCache*[T,K,V,E] = object
|
LruCache*[T,K,V,E] = object
|
||||||
data*: LruData[K,V] ## Cache data, can be serialised
|
data*: LruData[K,V] ## Cache data, can be serialised
|
||||||
|
@ -78,7 +81,7 @@ proc clearLruCache*[T,K,V,E](cache: var LruCache[T,K,V,E])
|
||||||
## Reset/clear an initialised LRU cache.
|
## Reset/clear an initialised LRU cache.
|
||||||
cache.data.first.reset
|
cache.data.first.reset
|
||||||
cache.data.last.reset
|
cache.data.last.reset
|
||||||
cache.data.tab = newTable[K,LruItem[K,V]](cache.data.maxItems.nextPowerOfTwo)
|
cache.data.tab = initTable[K,LruItem[K,V]](cache.data.maxItems.nextPowerOfTwo)
|
||||||
|
|
||||||
|
|
||||||
proc initLruCache*[T,K,V,E](cache: var LruCache[T,K,V,E];
|
proc initLruCache*[T,K,V,E](cache: var LruCache[T,K,V,E];
|
||||||
|
@ -176,14 +179,13 @@ proc read*[K,V](rlp: var Rlp; Q: type LruData[K,V]): Q {.inline.} =
|
||||||
result.maxItems = rlp.read(int)
|
result.maxItems = rlp.read(int)
|
||||||
result.first = rlp.read(K)
|
result.first = rlp.read(K)
|
||||||
result.last = rlp.read(K)
|
result.last = rlp.read(K)
|
||||||
result.tab = newTable[K,LruItem[K,V]](result.maxItems.nextPowerOfTwo)
|
|
||||||
for w in rlp.items:
|
for w in rlp.items:
|
||||||
let (key,value) = w.read((K,LruItem[K,V]))
|
let (key,value) = w.read((K,LruItem[K,V]))
|
||||||
result.tab[key] = value
|
result.tab[key] = value
|
||||||
|
|
||||||
|
|
||||||
proc specs*[T,K,V,E](cache: var LruCache[T,K,V,E]):
|
proc specs*[T,K,V,E](cache: var LruCache[T,K,V,E]):
|
||||||
(int, K, K, TableRef[K,LruItem[K,V]]) =
|
(int, K, K, Table[K,LruItem[K,V]]) =
|
||||||
## Returns cache data & specs `(maxItems,firstKey,lastKey,tableRef)` for
|
## Returns cache data & specs `(maxItems,firstKey,lastKey,tableRef)` for
|
||||||
## debugging and testing.
|
## debugging and testing.
|
||||||
(cache.data.maxItems, cache.data.first, cache.data.last, cache.data.tab)
|
(cache.data.maxItems, cache.data.first, cache.data.last, cache.data.tab)
|
||||||
|
|
|
@ -46,7 +46,7 @@ proc first[T,K,V,E](cache: var LruCache[T,K,V,E]): K =
|
||||||
proc last[T,K,V,E](cache: var LruCache[T,K,V,E]): K =
|
proc last[T,K,V,E](cache: var LruCache[T,K,V,E]): K =
|
||||||
cache.specs[2]
|
cache.specs[2]
|
||||||
|
|
||||||
proc tab[T,K,V,E](cache: var LruCache[T,K,V,E]): TableRef[K,LruItem[K,V]] =
|
proc tab[T,K,V,E](cache: var LruCache[T,K,V,E]): Table[K,LruItem[K,V]] =
|
||||||
cache.specs[3]
|
cache.specs[3]
|
||||||
|
|
||||||
|
|
||||||
|
@ -135,6 +135,26 @@ proc filledTestCache(noisy: bool): LruCache[int,int,string,int] =
|
||||||
proc doFillUpTest(noisy: bool) =
|
proc doFillUpTest(noisy: bool) =
|
||||||
discard filledTestCache(noisy)
|
discard filledTestCache(noisy)
|
||||||
|
|
||||||
|
|
||||||
|
proc doDeepCopyTest(noisy: bool) =
|
||||||
|
|
||||||
|
proc say(a: varargs[string]) =
|
||||||
|
say(noisy = noisy, args = a)
|
||||||
|
|
||||||
|
var
|
||||||
|
c1 = filledTestCache(false)
|
||||||
|
c2 = c1
|
||||||
|
|
||||||
|
doAssert c1 == c2
|
||||||
|
discard c1.getLruItem(77)
|
||||||
|
|
||||||
|
say &"c1Specs: {c1.maxItems} {c1.first} {c1.last} ..."
|
||||||
|
say &"c2Specs: {c2.maxItems} {c2.first} {c2.last} ..."
|
||||||
|
|
||||||
|
doAssert c1 != c2
|
||||||
|
doAssert c1.tab != c2.tab
|
||||||
|
|
||||||
|
|
||||||
proc doSerialiserTest(noisy: bool) =
|
proc doSerialiserTest(noisy: bool) =
|
||||||
|
|
||||||
proc say(a: varargs[string]) =
|
proc say(a: varargs[string]) =
|
||||||
|
@ -193,6 +213,9 @@ proc lruCacheMain*(noisy = defined(debug)) =
|
||||||
test "Fill Up":
|
test "Fill Up":
|
||||||
doFillUpTest(noisy)
|
doFillUpTest(noisy)
|
||||||
|
|
||||||
|
test "Deep Copy Semantics":
|
||||||
|
doDeepCopyTest(noisy)
|
||||||
|
|
||||||
test "Rlp Serialise & Load":
|
test "Rlp Serialise & Load":
|
||||||
doSerialiserTest(noisy)
|
doSerialiserTest(noisy)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue