Skip to content

Commit

Permalink
perf: migrate rbtree to js-sdsl (#2285)
Browse files Browse the repository at this point in the history
* perf: migrate rbtree to js-sdsl

* chore: remove functional red black tree

Co-authored-by: yaozilong.msy <yaozilong.msy@bytedance.com>
  • Loading branch information
ZLY201 and yaozilong.msy committed Sep 15, 2022
1 parent 295deaa commit cfa99af
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 37 deletions.
16 changes: 12 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/statemanager/package.json
Expand Up @@ -47,6 +47,6 @@
"@ethereumjs/util": "^8.0.0",
"debug": "^4.3.3",
"ethereum-cryptography": "^1.1.2",
"functional-red-black-tree": "^1.0.1"
"js-sdsl": "^4.1.4"
}
}
59 changes: 29 additions & 30 deletions packages/statemanager/src/cache.ts
@@ -1,8 +1,10 @@
import { Account } from '@ethereumjs/util'
// eslint-disable-next-line implicit-dependencies/no-implicit
import { OrderedMap } from 'js-sdsl'

import type { Address } from '@ethereumjs/util'

const Tree = require('functional-red-black-tree')
// eslint-disable-next-line implicit-dependencies/no-implicit
import type { OrderedMapIterator } from 'js-sdsl'

export type getCb = (address: Address) => Promise<Account | undefined>
export type putCb = (keyBuf: Buffer, accountRlp: Buffer) => Promise<void>
Expand All @@ -18,15 +20,17 @@ export interface CacheOpts {
* @ignore
*/
export class Cache {
_cache: any
_cache: OrderedMap<any, any>
_cacheEnd: OrderedMapIterator<any, any>
_checkpoints: any[]

_getCb: getCb
_putCb: putCb
_deleteCb: deleteCb

constructor(opts: CacheOpts) {
this._cache = Tree()
this._cache = new OrderedMap()
this._cacheEnd = this._cache.end()
this._getCb = opts.getCb
this._putCb = opts.putCb
this._deleteCb = opts.deleteCb
Expand Down Expand Up @@ -60,10 +64,11 @@ export class Cache {
const keyStr = key.buf.toString('hex')

const it = this._cache.find(keyStr)
if (it.node !== null) {
const rlp = it.value.val
if (!it.equals(this._cacheEnd)) {
const value = it.pointer[1]
const rlp = value.val
const account = Account.fromRlpSerializedAccount(rlp)
;(account as any).virtual = it.value.virtual
;(account as any).virtual = value.virtual
return account
}
}
Expand All @@ -75,8 +80,8 @@ export class Cache {
keyIsDeleted(key: Address): boolean {
const keyStr = key.buf.toString('hex')
const it = this._cache.find(keyStr)
if (it.node !== null) {
return it.value.deleted
if (!it.equals(this._cacheEnd)) {
return it.pointer[1].deleted
}
return false
}
Expand Down Expand Up @@ -108,24 +113,22 @@ export class Cache {
* and removing accounts that have been deleted.
*/
async flush(): Promise<void> {
const it = this._cache.begin
let next = true
while (next) {
if (it.value?.modified === true) {
it.value.modified = false
const keyBuf = Buffer.from(it.key, 'hex')
if (it.value.deleted === false) {
const accountRlp = it.value.val
const it = this._cache.begin()
while (!it.equals(this._cacheEnd)) {
const value = it.pointer[1]
if (value.modified === true) {
value.modified = false
const keyBuf = Buffer.from(it.pointer[0], 'hex')
if (value.deleted === false) {
const accountRlp = value.val
await this._putCb(keyBuf, accountRlp)
} else {
it.value.deleted = true
it.value.virtual = true
it.value.val = new Account().serialize()
value.deleted = true
value.virtual = true
value.val = new Account().serialize()
await this._deleteCb(keyBuf)
}
}

next = it.hasNext
it.next()
}
}
Expand All @@ -135,14 +138,15 @@ export class Cache {
* later on be reverted or commited.
*/
checkpoint(): void {
this._checkpoints.push(this._cache)
this._checkpoints.push(new OrderedMap(this._cache))
}

/**
* Revert changes to cache last checkpoint (no effect on trie).
*/
revert(): void {
this._cache = this._checkpoints.pop()
this._cacheEnd = this._cache.end()
}

/**
Expand All @@ -156,7 +160,7 @@ export class Cache {
* Clears cache.
*/
clear(): void {
this._cache = Tree()
this._cache.clear()
}

/**
Expand Down Expand Up @@ -184,12 +188,7 @@ export class Cache {
virtual = false
): void {
const keyHex = key.buf.toString('hex')
const it = this._cache.find(keyHex)
const val = value.serialize()
if (it.node !== null) {
this._cache = it.update({ val, modified, deleted, virtual })
} else {
this._cache = this._cache.insert(keyHex, { val, modified, deleted, virtual })
}
this._cache.setElement(keyHex, { val, modified, deleted, virtual })
}
}
2 changes: 1 addition & 1 deletion packages/statemanager/tests/stateManager.spec.ts
Expand Up @@ -106,7 +106,7 @@ tape('StateManager', (t) => {

const res2 = await stateManager.getAccount(address)

st.equal(stateManager._cache._cache.keys[0], address.buf.toString('hex'))
st.equal(stateManager._cache._cache.begin().pointer[0], address.buf.toString('hex'))
st.ok(res1.serialize().equals(res2.serialize()))

st.end()
Expand Down
1 change: 0 additions & 1 deletion packages/vm/package.json
Expand Up @@ -69,7 +69,6 @@
"async-eventemitter": "^0.2.4",
"debug": "^4.3.3",
"ethereum-cryptography": "^1.1.2",
"functional-red-black-tree": "^1.0.1",
"mcl-wasm": "^0.7.1",
"rustbn.js": "~0.2.0"
},
Expand Down

0 comments on commit cfa99af

Please sign in to comment.