mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-11-25 23:42:23 +00:00
mpt: do not allocate new buffer when updating dirty node
Running time becomes faster under high load while staying the same in the average case. Memory allocation done in `Trie` goes down by about ~10% (even more, actually).
This commit is contained in:
parent
9fcee12276
commit
168ba7960c
3 changed files with 15 additions and 10 deletions
|
@ -63,7 +63,7 @@ func (b *BaseNode) updateHash(n Node) {
|
||||||
|
|
||||||
// updateCache updates hash and bytes fields for this BaseNode.
|
// updateCache updates hash and bytes fields for this BaseNode.
|
||||||
func (b *BaseNode) updateBytes(n Node) {
|
func (b *BaseNode) updateBytes(n Node) {
|
||||||
buf := io.NewBufBinWriter()
|
buf := io.NewBufBinWriterPreAlloc(b.bytes)
|
||||||
encodeNodeWithType(n, buf.BinWriter)
|
encodeNodeWithType(n, buf.BinWriter)
|
||||||
b.bytes = buf.Bytes()
|
b.bytes = buf.Bytes()
|
||||||
b.bytesValid = true
|
b.bytesValid = true
|
||||||
|
|
|
@ -418,31 +418,29 @@ func (t *Trie) updateRefCount(h util.Uint256) int32 {
|
||||||
func (t *Trie) addRef(h util.Uint256, bs []byte) {
|
func (t *Trie) addRef(h util.Uint256, bs []byte) {
|
||||||
node := t.refcount[h]
|
node := t.refcount[h]
|
||||||
if node == nil {
|
if node == nil {
|
||||||
|
data := make([]byte, len(bs))
|
||||||
|
copy(data, bs)
|
||||||
t.refcount[h] = &cachedNode{
|
t.refcount[h] = &cachedNode{
|
||||||
refcount: 1,
|
refcount: 1,
|
||||||
bytes: bs,
|
bytes: data,
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
node.refcount++
|
node.refcount++
|
||||||
if node.bytes == nil {
|
|
||||||
node.bytes = bs
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Trie) removeRef(h util.Uint256, bs []byte) {
|
func (t *Trie) removeRef(h util.Uint256, bs []byte) {
|
||||||
node := t.refcount[h]
|
node := t.refcount[h]
|
||||||
if node == nil {
|
if node == nil {
|
||||||
|
data := make([]byte, len(bs))
|
||||||
|
copy(data, bs)
|
||||||
t.refcount[h] = &cachedNode{
|
t.refcount[h] = &cachedNode{
|
||||||
refcount: -1,
|
refcount: -1,
|
||||||
bytes: bs,
|
bytes: data,
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
node.refcount--
|
node.refcount--
|
||||||
if node.bytes == nil {
|
|
||||||
node.bytes = bs
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Trie) getFromStore(h util.Uint256) (Node, error) {
|
func (t *Trie) getFromStore(h util.Uint256) (Node, error) {
|
||||||
|
@ -462,7 +460,8 @@ func (t *Trie) getFromStore(h util.Uint256) (Node, error) {
|
||||||
data = data[:len(data)-4]
|
data = data[:len(data)-4]
|
||||||
node := t.refcount[h]
|
node := t.refcount[h]
|
||||||
if node != nil {
|
if node != nil {
|
||||||
node.bytes = data
|
node.bytes = make([]byte, len(data))
|
||||||
|
copy(node.bytes, data)
|
||||||
node.initial = int32(r.ReadU32LE())
|
node.initial = int32(r.ReadU32LE())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,12 @@ func NewBufBinWriter() *BufBinWriter {
|
||||||
return &BufBinWriter{BinWriter: NewBinWriterFromIO(b), buf: b}
|
return &BufBinWriter{BinWriter: NewBinWriterFromIO(b), buf: b}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewBufBinWriterPreAlloc makes a BufBinWriter using preallocated buffer.
|
||||||
|
func NewBufBinWriterPreAlloc(buf []byte) *BufBinWriter {
|
||||||
|
b := bytes.NewBuffer(buf[:0])
|
||||||
|
return &BufBinWriter{BinWriter: NewBinWriterFromIO(b), buf: b}
|
||||||
|
}
|
||||||
|
|
||||||
// Len returns the number of bytes of the unread portion of the buffer.
|
// Len returns the number of bytes of the unread portion of the buffer.
|
||||||
func (bw *BufBinWriter) Len() int {
|
func (bw *BufBinWriter) Len() int {
|
||||||
return bw.buf.Len()
|
return bw.buf.Len()
|
||||||
|
|
Loading…
Reference in a new issue