From 42ee5f707720a0275f0d069f74c8a9dc9187e345 Mon Sep 17 00:00:00 2001 From: akartasov Date: Mon, 10 Mar 2025 17:36:49 +0700 Subject: [PATCH] feat: add snapshot counter to branches and list of the clones to snapshot details (#572) --- engine/internal/cloning/snapshots.go | 20 +++++++++++--------- engine/internal/cloning/snapshots_test.go | 10 ++++++---- engine/internal/srv/branch.go | 22 ++++++++++++++-------- engine/pkg/models/branch.go | 11 ++++++----- engine/pkg/models/snapshot.go | 1 + 5 files changed, 38 insertions(+), 26 deletions(-) diff --git a/engine/internal/cloning/snapshots.go b/engine/internal/cloning/snapshots.go index c067f170f..827d0b7d7 100644 --- a/engine/internal/cloning/snapshots.go +++ b/engine/internal/cloning/snapshots.go @@ -32,13 +32,13 @@ func (c *Base) fetchSnapshots() error { var latestSnapshot *models.Snapshot snapshots := make(map[string]*models.Snapshot, len(entries)) - cloneCounter := c.cloneCounter() + cloneCounters := c.counterClones() for _, entry := range entries { - numClones := 0 + cloneList := []string{} - if num, ok := cloneCounter[entry.ID]; ok { - numClones = num + if foundList, ok := cloneCounters[entry.ID]; ok { + cloneList = foundList } currentSnapshot := &models.Snapshot{ @@ -49,7 +49,8 @@ func (c *Base) fetchSnapshots() error { LogicalSize: entry.LogicalReferenced, Pool: entry.Pool, Branch: entry.Branch, - NumClones: numClones, + NumClones: len(cloneList), + Clones: cloneList, } snapshots[entry.ID] = currentSnapshot @@ -63,20 +64,21 @@ func (c *Base) fetchSnapshots() error { return nil } -func (c *Base) cloneCounter() map[string]int { - cloneCounter := make(map[string]int) +func (c *Base) counterClones() map[string][]string { + clones := make(map[string][]string, 0) c.cloneMutex.RLock() for cloneName := range c.clones { if c.clones[cloneName] != nil && c.clones[cloneName].Clone.Snapshot != nil { - cloneCounter[c.clones[cloneName].Clone.Snapshot.ID]++ + snapshotID := c.clones[cloneName].Clone.Snapshot.ID + clones[snapshotID] = append(clones[snapshotID], cloneName) } } c.cloneMutex.RUnlock() - return cloneCounter + return clones } func (c *Base) resetSnapshots(snapshotMap map[string]*models.Snapshot, latestSnapshot *models.Snapshot) { diff --git a/engine/internal/cloning/snapshots_test.go b/engine/internal/cloning/snapshots_test.go index c068c1e28..2034d023f 100644 --- a/engine/internal/cloning/snapshots_test.go +++ b/engine/internal/cloning/snapshots_test.go @@ -158,11 +158,13 @@ func TestInitialCloneCounter(t *testing.T) { c.clones["test_clone002"] = cloneWrapper02 c.clones["test_clone003"] = cloneWrapper03 - counters := c.cloneCounter() + counters := c.counterClones() - require.Equal(t, 2, len(counters)) - require.Equal(t, 2, counters["testSnapshotID"]) - require.Equal(t, 1, counters["testSnapshotID2"]) + require.Len(t, counters, 2) + require.Len(t, counters["testSnapshotID"], 2) + require.Len(t, counters["testSnapshotID2"], 1) + require.Len(t, counters["testSnapshotID3"], 0) + require.ElementsMatch(t, []string{"test_clone001", "test_clone002"}, counters["testSnapshotID"]) } func TestLatestSnapshots(t *testing.T) { diff --git a/engine/internal/srv/branch.go b/engine/internal/srv/branch.go index 08abf48c5..e017d9e3c 100644 --- a/engine/internal/srv/branch.go +++ b/engine/internal/srv/branch.go @@ -57,12 +57,15 @@ func (s *Server) listBranches(w http.ResponseWriter, r *http.Request) { continue } + numSnapshots, parentSnapshot := findBranchParent(repo.Snapshots, snapshotDetails.ID, branchEntity.Name) + branchView := models.BranchView{ - Name: branchEntity.Name, - Parent: findBranchParent(repo.Snapshots, snapshotDetails.ID, branchEntity.Name), - DataStateAt: snapshotDetails.DataStateAt, - SnapshotID: snapshotDetails.ID, - Dataset: snapshotDetails.Dataset, + Name: branchEntity.Name, + Parent: parentSnapshot, + DataStateAt: snapshotDetails.DataStateAt, + SnapshotID: snapshotDetails.ID, + Dataset: snapshotDetails.Dataset, + NumSnapshots: numSnapshots, } if position, ok := branchRegistry[branchEntity.Name]; ok { @@ -83,13 +86,16 @@ func (s *Server) listBranches(w http.ResponseWriter, r *http.Request) { } } -func findBranchParent(snapshots map[string]models.SnapshotDetails, parentID, branch string) string { +func findBranchParent(snapshots map[string]models.SnapshotDetails, parentID, branch string) (int, string) { + snapshotCounter := 0 + for i := len(snapshots); i > 0; i-- { snapshotPointer := snapshots[parentID] + snapshotCounter++ if containsString(snapshotPointer.Root, branch) { if len(snapshotPointer.Branch) > 0 { - return snapshotPointer.Branch[0] + return snapshotCounter, snapshotPointer.Branch[0] } break @@ -102,7 +108,7 @@ func findBranchParent(snapshots map[string]models.SnapshotDetails, parentID, bra parentID = snapshotPointer.Parent } - return "-" + return snapshotCounter, "-" } func containsString(slice []string, s string) bool { diff --git a/engine/pkg/models/branch.go b/engine/pkg/models/branch.go index 47d8358f1..c603a1746 100644 --- a/engine/pkg/models/branch.go +++ b/engine/pkg/models/branch.go @@ -33,11 +33,12 @@ type SnapshotDetails struct { // BranchView describes branch view. type BranchView struct { - Name string `json:"name"` - Parent string `json:"parent"` - DataStateAt string `json:"dataStateAt"` - SnapshotID string `json:"snapshotID"` - Dataset string `json:"dataset"` + Name string `json:"name"` + Parent string `json:"parent"` + DataStateAt string `json:"dataStateAt"` + SnapshotID string `json:"snapshotID"` + Dataset string `json:"dataset"` + NumSnapshots int `json:"numSnapshots"` } // BranchEntity defines a branch-snapshot pair. diff --git a/engine/pkg/models/snapshot.go b/engine/pkg/models/snapshot.go index 11ac1fba2..62e06fae8 100644 --- a/engine/pkg/models/snapshot.go +++ b/engine/pkg/models/snapshot.go @@ -13,6 +13,7 @@ type Snapshot struct { LogicalSize uint64 `json:"logicalSize"` Pool string `json:"pool"` NumClones int `json:"numClones"` + Clones []string `json:"clones"` Branch string `json:"branch"` } -- GitLab