mirror of
https://github.com/status-im/nimbus-eth2.git
synced 2025-01-22 04:24:05 +00:00
db: compress with snappy
* 3gb vs 12gb for 4000 epochs of witti * 3-4x sync blocks/sec performance improvement on my FDE SSD drive * generate less quirky code for primitive types
This commit is contained in:
parent
ed054d601f
commit
360ebd705f
@ -1,8 +1,8 @@
|
||||
{.push raises: [Defect].}
|
||||
|
||||
import
|
||||
typetraits, stew/[results, endians2],
|
||||
serialization, chronicles,
|
||||
typetraits, stew/[results, objects, endians2],
|
||||
serialization, chronicles, snappy,
|
||||
eth/db/kvstore,
|
||||
./spec/[datatypes, digest, crypto],
|
||||
./ssz/[ssz_serialization, merkleization], ./state_transition
|
||||
@ -66,14 +66,39 @@ func subkey(root: Eth2Digest, slot: Slot): array[40, byte] =
|
||||
proc init*(T: type BeaconChainDB, backend: KVStoreRef): BeaconChainDB =
|
||||
T(backend: backend)
|
||||
|
||||
proc snappyEncode(inp: openArray[byte]): seq[byte] =
|
||||
try:
|
||||
snappy.encode(inp)
|
||||
except CatchableError as err:
|
||||
raiseAssert err.msg
|
||||
|
||||
proc put(db: BeaconChainDB, key: openArray[byte], v: Eth2Digest) =
|
||||
db.backend.put(key, v.data).expect("working database")
|
||||
|
||||
proc put(db: BeaconChainDB, key: openArray[byte], v: auto) =
|
||||
db.backend.put(key, SSZ.encode(v)).expect("working database")
|
||||
db.backend.put(key, snappyEncode(SSZ.encode(v))).expect("working database")
|
||||
|
||||
proc get(db: BeaconChainDB, key: openArray[byte], T: type Eth2Digest): Opt[T] =
|
||||
var res: Opt[T]
|
||||
proc decode(data: openArray[byte]) =
|
||||
if data.len == 32:
|
||||
res.ok Eth2Digest(data: toArray(32, data))
|
||||
else:
|
||||
# If the data can't be deserialized, it could be because it's from a
|
||||
# version of the software that uses a different SSZ encoding
|
||||
warn "Unable to deserialize data, old database?",
|
||||
typ = name(T), dataLen = data.len
|
||||
discard
|
||||
|
||||
discard db.backend.get(key, decode).expect("working database")
|
||||
|
||||
res
|
||||
|
||||
proc get(db: BeaconChainDB, key: openArray[byte], T: typedesc): Opt[T] =
|
||||
var res: Opt[T]
|
||||
proc decode(data: openArray[byte]) =
|
||||
try:
|
||||
res.ok SSZ.decode(data, T)
|
||||
res.ok SSZ.decode(snappy.decode(data), T)
|
||||
except SerializationError as e:
|
||||
# If the data can't be deserialized, it could be because it's from a
|
||||
# version of the software that uses a different SSZ encoding
|
||||
@ -99,8 +124,7 @@ proc putState*(db: BeaconChainDB, value: BeaconState) =
|
||||
|
||||
proc putStateRoot*(db: BeaconChainDB, root: Eth2Digest, slot: Slot,
|
||||
value: Eth2Digest) =
|
||||
db.backend.put(subkey(root, slot), value.data).expect(
|
||||
"working database")
|
||||
db.put(subkey(root, slot), value)
|
||||
|
||||
proc putBlock*(db: BeaconChainDB, value: SignedBeaconBlock) =
|
||||
db.putBlock(hash_tree_root(value.message), value)
|
||||
@ -116,10 +140,10 @@ proc delStateRoot*(db: BeaconChainDB, root: Eth2Digest, slot: Slot) =
|
||||
db.backend.del(subkey(root, slot)).expect("working database")
|
||||
|
||||
proc putHeadBlock*(db: BeaconChainDB, key: Eth2Digest) =
|
||||
db.backend.put(subkey(kHeadBlock), key.data).expect("working database")
|
||||
db.put(subkey(kHeadBlock), key)
|
||||
|
||||
proc putTailBlock*(db: BeaconChainDB, key: Eth2Digest) =
|
||||
db.backend.put(subkey(kTailBlock), key.data).expect("working database")
|
||||
db.put(subkey(kTailBlock), key)
|
||||
|
||||
proc getBlock*(db: BeaconChainDB, key: Eth2Digest): Opt[SignedBeaconBlock] =
|
||||
db.get(subkey(SignedBeaconBlock, key), SignedBeaconBlock)
|
||||
@ -141,7 +165,7 @@ proc getState*(
|
||||
proc decode(data: openArray[byte]) =
|
||||
try:
|
||||
# TODO can't write to output directly..
|
||||
assign(outputAddr[], SSZ.decode(data, BeaconState))
|
||||
assign(outputAddr[], SSZ.decode(snappy.decode(data), BeaconState))
|
||||
except SerializationError as e:
|
||||
# If the data can't be deserialized, it could be because it's from a
|
||||
# version of the software that uses a different SSZ encoding
|
||||
|
@ -661,10 +661,16 @@ func assign*[T](tgt: var T, src: T) =
|
||||
# time in it - `assign`, in the same test, doesn't even show in the perf trace
|
||||
|
||||
when supportsCopyMem(T):
|
||||
copyMem(addr tgt, unsafeAddr src, sizeof(tgt))
|
||||
when sizeof(src) <= sizeof(int):
|
||||
tgt = src
|
||||
else:
|
||||
copyMem(addr tgt, unsafeAddr src, sizeof(tgt))
|
||||
elif T is object|tuple:
|
||||
for t, s in fields(tgt, src):
|
||||
assign(t, s)
|
||||
when supportsCopyMem(type s) and sizeof(s) <= sizeof(int) * 2:
|
||||
t = s # Shortcut
|
||||
else:
|
||||
assign(t, s)
|
||||
elif T is List|BitList:
|
||||
assign(distinctBase tgt, distinctBase src)
|
||||
elif T is seq:
|
||||
|
Loading…
x
Reference in New Issue
Block a user