Index: node.go |
diff --git a/node.go b/node.go |
index 88ff70f7bae914b189ff1fde9889ad1cca56a5f1..4ee1fa2bdbcf614afdb6dccaf8f17f2fd7356930 100644 |
--- a/node.go |
+++ b/node.go |
@@ -15,10 +15,10 @@ type node struct { |
next *node // For free-list tracking. |
} |
+var nodeLocGL = sync.RWMutex{} |
+ |
// A persistable node and its persistence location. |
type nodeLoc struct { |
- 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. |
@@ -27,50 +27,59 @@ type nodeLoc struct { |
var empty_nodeLoc = &nodeLoc{} // Sentinel. |
func (nloc *nodeLoc) Loc() *ploc { |
- nloc.m.Lock() |
- defer nloc.m.Unlock() |
+ nodeLocGL.RLock() |
+ defer nodeLocGL.RUnlock() |
return nloc.loc |
} |
func (nloc *nodeLoc) setLoc(n *ploc) { |
- nloc.m.Lock() |
- defer nloc.m.Unlock() |
+ nodeLocGL.Lock() |
+ defer nodeLocGL.Unlock() |
nloc.loc = n |
} |
func (nloc *nodeLoc) Node() *node { |
- nloc.m.Lock() |
- defer nloc.m.Unlock() |
+ nodeLocGL.RLock() |
+ defer nodeLocGL.RUnlock() |
return nloc.node |
} |
func (nloc *nodeLoc) setNode(n *node) { |
- nloc.m.Lock() |
- defer nloc.m.Unlock() |
+ nodeLocGL.Lock() |
+ defer nodeLocGL.Unlock() |
nloc.node = n |
} |
+func (nloc *nodeLoc) LocNode() (*ploc, *node) { |
+ nodeLocGL.RLock() |
+ defer nodeLocGL.RUnlock() |
+ return nloc.loc, nloc.node |
+} |
+ |
func (nloc *nodeLoc) Copy(src *nodeLoc) *nodeLoc { |
if src == nil { |
return nloc.Copy(empty_nodeLoc) |
} |
- newloc := src.Loc() |
- newnode := src.Node() |
- nloc.m.Lock() |
- defer nloc.m.Unlock() |
- nloc.loc = newloc |
- nloc.node = newnode |
+ nodeLocGL.Lock() |
+ defer nodeLocGL.Unlock() |
+ // NOTE: This trick only works because of the global lock. No reason to lock |
+ // src independently of nlock. |
+ nloc.loc = src.loc |
+ nloc.node = src.node |
return nloc |
} |
func (nloc *nodeLoc) isEmpty() bool { |
- return nloc == nil || (nloc.Loc().isEmpty() && nloc.Node() == nil) |
+ nodeLocGL.RLock() |
+ defer nodeLocGL.RUnlock() |
+ return nloc == nil || (nloc.loc.isEmpty() && nloc.node == nil) |
} |
func (nloc *nodeLoc) write(o *Store) error { |
- if nloc != nil && nloc.Loc().isEmpty() { |
- node := nloc.Node() |
+ loc, node := nloc.LocNode() |
+ |
+ if nloc != nil && loc.isEmpty() { |
if node == nil { |
return nil |
} |
@@ -102,11 +111,10 @@ func (nloc *nodeLoc) read(o *Store) (n *node, err error) { |
if nloc == nil { |
return nil, nil |
} |
- n = nloc.Node() |
+ loc, n := nloc.LocNode() |
if n != nil { |
return n, nil |
} |
- loc := nloc.Loc() |
if loc.isEmpty() { |
return nil, nil |
} |