Use sorted RLP serialisation for LRU cache

why:
  previously, table data were stored with the table iterator. while
  loading a table with permuted entries will always reconstruct equivalent
  tables (in the sense of `==`), serialisation data are not comparable.

  this patch produces always the same serialised data for equivalent
  tables.
This commit is contained in:
Jordan Hrycaj 2021-05-25 18:44:55 +01:00 committed by Jordan Hrycaj
parent b83b47e541
commit 7b72109afa
2 changed files with 43 additions and 2 deletions

View File

@ -159,8 +159,16 @@ proc append*[K,V](rw: var RlpWriter; data: LruData[K,V]) {.inline.} =
rw.append(data.first)
rw.append(data.last)
rw.startList(data.tab.len)
for key,value in data.tab.pairs:
# store keys in LRU order
if 0 < data.tab.len:
var key = data.first
for _ in 0 ..< data.tab.len - 1:
var value = data.tab[key]
rw.append((key, value))
key = value.nxt
rw.append((key, data.tab[key]))
if key != data.last:
raiseAssert "Garbled LRU cache next/prv references"
proc read*[K,V](rlp: var Rlp; Q: type LruData[K,V]): Q {.inline.} =
## Generic support for `rlp.decode(bytes)` for loading the data part

View File

@ -157,6 +157,35 @@ proc doSerialiserTest(noisy: bool) =
doAssert s1 == rlp.encode(c2.data)
proc doSerialiseSingleEntry(noisy: bool) =
proc say(a: varargs[string]) =
say(noisy = noisy, args = a)
var
c1 = createTestCache()
value = c1.getLruItem(77)
queue = c1.toKeyList
values = c1.toValueList
say &"c1: append {value} => {queue}"
var
s1 = rlp.encode(c1.data)
c2 = createTestCache()
say &"serialised[{s1.len}]: {s1}"
c2.clearLruCache
doAssert c1 != c2
c2.data = s1.decode(type c2.data)
doAssert c1 == c2
say &"c2Specs: {c2.maxItems} {c2.first} {c2.last} ..."
doAssert s1 == rlp.encode(c2.data)
proc lruCacheMain*(noisy = defined(debug)) =
suite "LRU Cache":
@ -167,6 +196,10 @@ proc lruCacheMain*(noisy = defined(debug)) =
test "Rlp Serialise & Load":
doSerialiserTest(noisy)
test "Rlp Single Entry Test":
doSerialiseSingleEntry(noisy)
when isMainModule:
lruCacheMain()