Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 74 additions & 6 deletions consensus/XDPoS/utils/pool.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package utils

import (
"encoding/json"
"sync"

"github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/log"
)

type PoolObj interface {
Expand All @@ -21,8 +23,11 @@ func NewPool() *Pool {
objList: make(map[string]map[common.Hash]PoolObj),
}
}

func (p *Pool) Get() map[string]map[common.Hash]PoolObj {
return p.objList
p.lock.RLock()
defer p.lock.RUnlock()
return p.getSnapshot()
}

func (p *Pool) Add(obj PoolObj) (int, map[common.Hash]PoolObj) {
Expand All @@ -36,10 +41,13 @@ func (p *Pool) Add(obj PoolObj) (int, map[common.Hash]PoolObj) {
}
objListKeyed[obj.Hash()] = obj
numOfItems := len(objListKeyed)
return numOfItems, objListKeyed
safeCopy := p.getSafePoolObjMap(objListKeyed)
return numOfItems, safeCopy
}

func (p *Pool) Size(obj PoolObj) int {
p.lock.Lock()
defer p.lock.Unlock()
poolKey := obj.PoolKey()
objListKeyed, ok := p.objList[poolKey]
if !ok {
Expand Down Expand Up @@ -84,8 +92,8 @@ func (p *Pool) Clear() {
}

func (p *Pool) GetObjsByKey(poolKey string) []PoolObj {
p.lock.Lock()
defer p.lock.Unlock()
p.lock.RLock()
defer p.lock.RUnlock()

objListKeyed, ok := p.objList[poolKey]
if !ok {
Expand All @@ -94,8 +102,68 @@ func (p *Pool) GetObjsByKey(poolKey string) []PoolObj {
objList := make([]PoolObj, len(objListKeyed))
cnt := 0
for _, obj := range objListKeyed {
objList[cnt] = obj
cnt += 1
objList[cnt] = p.getSafePoolObj(obj)
cnt++
}
return objList
}

// caller should hold lock
func (p *Pool) getSnapshot() map[string]map[common.Hash]PoolObj {
data, err := json.Marshal(p.objList)
if err != nil {
// This should never happen
log.Error("[getSafeCopy] Error while marshalling pool object list", "error", err)
return make(map[string]map[common.Hash]PoolObj)
}

var dataCopy map[string]map[common.Hash]PoolObj
err = json.Unmarshal(data, &dataCopy)
if err != nil {
// This should never happen
log.Error("[getSafeCopy] Error while unmarshalling pool object list", "error", err)
return make(map[string]map[common.Hash]PoolObj)
}

return dataCopy
}

// caller should hold lock
func (p *Pool) getSafePoolObjMap(objMap map[common.Hash]PoolObj) map[common.Hash]PoolObj {
data, err := json.Marshal(objMap)
if err != nil {
// This should never happen
log.Error("[getSafeCopy] Error while marshalling pool object list", "error", err)
return make(map[common.Hash]PoolObj)
}

var dataCopy map[common.Hash]PoolObj
err = json.Unmarshal(data, &dataCopy)
if err != nil {
// This should never happen
log.Error("[getSafeCopy] Error while unmarshalling pool object list", "error", err)
return make(map[common.Hash]PoolObj)
}

return dataCopy
}

// caller should hold lock
func (p *Pool) getSafePoolObj(obj PoolObj) PoolObj {
data, err := json.Marshal(obj)
if err != nil {
// This should never happen
log.Error("[getSafeCopy] Error while marshalling pool object list", "error", err)
return nil
}

var dataCopy PoolObj
err = json.Unmarshal(data, &dataCopy)
if err != nil {
// This should never happen
log.Error("[getSafeCopy] Error while unmarshalling pool object list", "error", err)
return nil
}

return dataCopy
}
Loading