| Index: node.go
|
| diff --git a/node.go b/node.go
|
| index b929f6c9f53c003ad639848a52300b67143beca7..88ff70f7bae914b189ff1fde9889ad1cca56a5f1 100644
|
| --- a/node.go
|
| +++ b/node.go
|
| @@ -3,8 +3,8 @@ package gkvlite
|
| import (
|
| "encoding/binary"
|
| "fmt"
|
| + "sync"
|
| "sync/atomic"
|
| - "unsafe"
|
| )
|
|
|
| // A persistable node.
|
| @@ -17,27 +17,50 @@ type node struct {
|
|
|
| // A persistable node and its persistence location.
|
| type nodeLoc struct {
|
| - loc unsafe.Pointer // *ploc - can be nil if node is dirty (not yet persisted).
|
| - node unsafe.Pointer // *node - can be nil if node is not fetched into memory yet.
|
| - next *nodeLoc // For free-list tracking.
|
| + m sync.Mutex
|
| +
|
| + loc *ploc // *ploc - can be nil if node is dirty (not yet persisted).
|
| + node *node // *node - can be nil if node is not fetched into memory yet.
|
| + next *nodeLoc // For free-list tracking.
|
| }
|
|
|
| var empty_nodeLoc = &nodeLoc{} // Sentinel.
|
|
|
| func (nloc *nodeLoc) Loc() *ploc {
|
| - return (*ploc)(atomic.LoadPointer(&nloc.loc))
|
| + nloc.m.Lock()
|
| + defer nloc.m.Unlock()
|
| + return nloc.loc
|
| +}
|
| +
|
| +func (nloc *nodeLoc) setLoc(n *ploc) {
|
| + nloc.m.Lock()
|
| + defer nloc.m.Unlock()
|
| + nloc.loc = n
|
| }
|
|
|
| func (nloc *nodeLoc) Node() *node {
|
| - return (*node)(atomic.LoadPointer(&nloc.node))
|
| + nloc.m.Lock()
|
| + defer nloc.m.Unlock()
|
| + return nloc.node
|
| +}
|
| +
|
| +func (nloc *nodeLoc) setNode(n *node) {
|
| + nloc.m.Lock()
|
| + defer nloc.m.Unlock()
|
| + nloc.node = n
|
| }
|
|
|
| func (nloc *nodeLoc) Copy(src *nodeLoc) *nodeLoc {
|
| if src == nil {
|
| return nloc.Copy(empty_nodeLoc)
|
| }
|
| - atomic.StorePointer(&nloc.loc, unsafe.Pointer(src.Loc()))
|
| - atomic.StorePointer(&nloc.node, unsafe.Pointer(src.Node()))
|
| + newloc := src.Loc()
|
| + newnode := src.Node()
|
| +
|
| + nloc.m.Lock()
|
| + defer nloc.m.Unlock()
|
| + nloc.loc = newloc
|
| + nloc.node = newnode
|
| return nloc
|
| }
|
|
|
| @@ -70,8 +93,7 @@ func (nloc *nodeLoc) write(o *Store) error {
|
| return err
|
| }
|
| atomic.StoreInt64(&o.size, offset+int64(length))
|
| - atomic.StorePointer(&nloc.loc,
|
| - unsafe.Pointer(&ploc{Offset: offset, Length: uint32(length)}))
|
| + nloc.setLoc(&ploc{Offset: offset, Length: uint32(length)})
|
| }
|
| return nil
|
| }
|
| @@ -102,13 +124,13 @@ func (nloc *nodeLoc) read(o *Store) (n *node, err error) {
|
| var p *ploc
|
| p = &ploc{}
|
| p, pos = p.read(b, pos)
|
| - n.item.loc = unsafe.Pointer(p)
|
| + n.item.loc = p
|
| p = &ploc{}
|
| p, pos = p.read(b, pos)
|
| - n.left.loc = unsafe.Pointer(p)
|
| + n.left.loc = p
|
| p = &ploc{}
|
| p, pos = p.read(b, pos)
|
| - n.right.loc = unsafe.Pointer(p)
|
| + n.right.loc = p
|
| n.numNodes = binary.BigEndian.Uint64(b[pos : pos+8])
|
| pos += 8
|
| n.numBytes = binary.BigEndian.Uint64(b[pos : pos+8])
|
| @@ -117,7 +139,7 @@ func (nloc *nodeLoc) read(o *Store) (n *node, err error) {
|
| return nil, fmt.Errorf("nodeLoc.read() pos: %v didn't match length: %v",
|
| pos, len(b))
|
| }
|
| - atomic.StorePointer(&nloc.node, unsafe.Pointer(n))
|
| + nloc.setNode(n)
|
| return n, nil
|
| }
|
|
|
|
|