blob: a13133950803229f104422345318d581409ba611 [file] [log] [blame]
package state
import (
"veyron/services/store/memstore/refs"
"veyron2/storage"
)
// refsExist returns true iff there is a value in the state for each reference.
func (sn *snapshot) refsExist(ids refs.Set) bool {
for it := ids.Iterator(); it.IsValid(); it.Next() {
id := it.Get().(*refs.Ref).ID
if !sn.idTable.Contains(&Cell{ID: id}) {
return false
}
}
return true
}
// updateRefs takes a set of references from <before> to <after>. Any reference
// in (<before> - <after>) should be decremented, and any reference in (<after>
// - <before>) should be incremented.
func (sn *MutableSnapshot) updateRefs(id storage.ID, beforeRefs, afterRefs refs.Set) {
it1 := beforeRefs.Iterator()
it2 := afterRefs.Iterator()
for it1.IsValid() && it2.IsValid() {
r1 := it1.Get().(*refs.Ref)
r2 := it2.Get().(*refs.Ref)
cmp := storage.CompareIDs(r1.ID, r2.ID)
switch {
case cmp < 0:
sn.removeRef(id, r1)
it1.Next()
case cmp > 0:
sn.addRef(id, r2)
it2.Next()
case cmp == 0:
it1.Next()
it2.Next()
}
}
for ; it1.IsValid(); it1.Next() {
sn.removeRef(id, it1.Get().(*refs.Ref))
}
for ; it2.IsValid(); it2.Next() {
sn.addRef(id, it2.Get().(*refs.Ref))
}
}
func (sn *MutableSnapshot) addRefs(id storage.ID, r refs.Set) {
r.Iter(func(it interface{}) bool {
sn.addRef(id, it.(*refs.Ref))
return true
})
}
func (sn *MutableSnapshot) removeRefs(id storage.ID, r refs.Set) {
r.Iter(func(it interface{}) bool {
sn.removeRef(id, it.(*refs.Ref))
return true
})
}
func (sn *MutableSnapshot) addRef(id storage.ID, r *refs.Ref) {
// Update refcount.
sn.ref(r.ID)
// Add the inverse link.
c := sn.Find(r.ID)
c.inRefs = c.inRefs.Put(&refs.Ref{ID: id, Path: r.Path, Label: r.Label})
}
func (sn *MutableSnapshot) removeRef(id storage.ID, r *refs.Ref) {
// Remove the inverse link.
c := sn.deref(r.ID)
c.inRefs = c.inRefs.Remove(&refs.Ref{ID: id, Path: r.Path, Label: r.Label})
// Update refcount.
sn.unref(r.ID)
}