summaryrefslogtreecommitdiff
path: root/lib/btrfsutil/graph.go
diff options
context:
space:
mode:
Diffstat (limited to 'lib/btrfsutil/graph.go')
-rw-r--r--lib/btrfsutil/graph.go53
1 files changed, 36 insertions, 17 deletions
diff --git a/lib/btrfsutil/graph.go b/lib/btrfsutil/graph.go
index ea33be7..fe7fe70 100644
--- a/lib/btrfsutil/graph.go
+++ b/lib/btrfsutil/graph.go
@@ -23,34 +23,52 @@ import (
)
type GraphNode struct {
+ Addr btrfsvol.LogicalAddr
Level uint8
Generation btrfsprim.Generation
Owner btrfsprim.ObjID
Items []btrfsprim.Key
}
-func (n GraphNode) MinItem() btrfsprim.Key {
- if len(n.Items) == 0 {
+func (n GraphNode) NumItems(g Graph) int {
+ switch n.Level {
+ case 0:
+ return len(n.Items)
+ default:
+ return len(g.EdgesFrom[n.Addr])
+ }
+}
+
+func (n GraphNode) MinItem(g Graph) btrfsprim.Key {
+ if n.NumItems(g) == 0 {
return btrfsprim.Key{}
}
- return n.Items[0]
+ switch n.Level {
+ case 0:
+ return n.Items[0]
+ default:
+ return g.EdgesFrom[n.Addr][0].ToKey
+ }
}
-func (n GraphNode) MaxItem() btrfsprim.Key {
- if len(n.Items) == 0 {
+func (n GraphNode) MaxItem(g Graph) btrfsprim.Key {
+ if n.NumItems(g) == 0 {
return btrfsprim.Key{}
}
- return n.Items[len(n.Items)-1]
+ switch n.Level {
+ case 0:
+ return n.Items[len(n.Items)-1]
+ default:
+ return g.EdgesFrom[n.Addr][len(g.EdgesFrom[n.Addr])-1].ToKey
+ }
}
func (n GraphNode) String() string {
if reflect.ValueOf(n).IsZero() {
return "{}"
}
- return fmt.Sprintf(`{lvl:%v, gen:%v, tree:%v, cnt:%v, min:(%v,%v,%v), max:(%v,%v,%v)}`,
- n.Level, n.Generation, n.Owner, len(n.Items),
- n.MinItem().ObjectID, n.MinItem().ItemType, n.MinItem().Offset,
- n.MaxItem().ObjectID, n.MaxItem().ItemType, n.MaxItem().Offset)
+ return fmt.Sprintf(`{lvl:%v, gen:%v, tree:%v, cnt:%v}`,
+ n.Level, n.Generation, n.Owner, len(n.Items))
}
type GraphEdge struct {
@@ -59,7 +77,7 @@ type GraphEdge struct {
// superblock.
FromRoot btrfsvol.LogicalAddr
FromNode btrfsvol.LogicalAddr
- FromItem int // only valid if one of FromRoot or FromNode is non-zero
+ FromSlot int // only valid if one of FromRoot or FromNode is non-zero
FromTree btrfsprim.ObjID
@@ -74,10 +92,10 @@ func (kp GraphEdge) String() string {
switch {
case kp.FromRoot != 0:
from = fmt.Sprintf("root@%v[%d]:%v",
- kp.FromRoot, kp.FromItem, kp.FromTree)
+ kp.FromRoot, kp.FromSlot, kp.FromTree)
case kp.FromNode != 0:
from = fmt.Sprintf("{node:%v, tree:%v}[%d]",
- kp.FromNode, kp.FromTree, kp.FromItem)
+ kp.FromNode, kp.FromTree, kp.FromSlot)
default:
from = fmt.Sprintf("superblock:%v", kp.FromTree)
}
@@ -103,8 +121,8 @@ func (g Graph) insertEdge(ptr *GraphEdge) {
if ptr.FromRoot != 0 && ptr.FromNode != 0 {
panic("kp.FromRoot and kp.FromNode should not both be set")
}
- if (ptr.FromRoot == 0 && ptr.FromNode == 0) && ptr.FromItem != 0 {
- panic("kp.FromItem should only be set if either kp.FromRoot or kp.FromItem is set")
+ if (ptr.FromRoot == 0 && ptr.FromNode == 0) && ptr.FromSlot != 0 {
+ panic("kp.FromSlot should only be set if either kp.FromRoot or kp.FromSlot is set")
}
g.EdgesFrom[ptr.FromNode] = append(g.EdgesFrom[ptr.FromNode], ptr)
g.EdgesTo[ptr.ToNode] = append(g.EdgesTo[ptr.ToNode], ptr)
@@ -150,6 +168,7 @@ func NewGraph(ctx context.Context, sb btrfstree.Superblock) Graph {
func (g Graph) InsertNode(node *btrfstree.Node) {
nodeData := GraphNode{
+ Addr: node.Head.Addr,
Level: node.Head.Level,
Generation: node.Head.Generation,
Owner: node.Head.Owner,
@@ -171,7 +190,7 @@ func (g Graph) InsertNode(node *btrfstree.Node) {
if itemBody, ok := item.Body.(*btrfsitem.Root); ok {
kps = append(kps, GraphEdge{
FromRoot: node.Head.Addr,
- FromItem: i,
+ FromSlot: i,
FromTree: item.Key.ObjectID,
ToNode: itemBody.ByteNr,
ToLevel: itemBody.Level,
@@ -186,7 +205,7 @@ func (g Graph) InsertNode(node *btrfstree.Node) {
for i, kp := range node.BodyInterior {
kps[i] = GraphEdge{
FromNode: node.Head.Addr,
- FromItem: i,
+ FromSlot: i,
FromTree: node.Head.Owner,
ToNode: kp.BlockPtr,
ToLevel: node.Head.Level - 1,