Repository: dragonflyoss/Dragonfly2
Pull request #1470 (2022-07-19 05:44:31)

feat: dag adds LenVertex and RangeVertex func
Signed-off-by: Gaius <gaius.qi@gmail.com>

<!--- Provide a general summary of your changes in the Title above -->

## Description
- DAG adds LenVertex and RangeVertex func.
<!--- Describe your changes in detail -->

## Related Issue

<!--- This project only accepts pull requests related to open issues -->
<!--- If suggesting a new feature or change, please discuss it in an issue first -->
<!--- If fixing a bug, there should be an issue describing it with steps to reproduce -->
<!--- Please link to the issue here: -->

## Motivation and Context

<!--- Why is this change required? What problem does it solve? -->

## Screenshots (if appropriate)

## Types of changes

<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->

- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
- [ ] Documentation Update (if none of the other choices apply)

## Checklist

<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->

- [ ] My change requires a change to the documentation.
- [ ] I have updated the documentation accordingly.
- [x] I have read the **CONTRIBUTING** document.
- [x] I have added tests to cover my changes.


codecov-commenter: # [Codecov](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1470?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss) Report
> Merging [#1470](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1470?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss) (113a380) into [main](https://codecov.io/gh/dragonflyoss/Dragonfly2/commit/311ca60a4b7072a42104015dd669ff975a48802c?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss) (311ca60) will **decrease** coverage by `0.04%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1470/graphs/tree.svg?width=650&height=150&src=pr&token=PUICJYSAT7&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss)](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1470?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss)

```diff
@@            Coverage Diff             @@
##             main    #1470      +/-   ##
==========================================
- Coverage   43.92%   43.87%   -0.05%     
==========================================
  Files         120      120              
  Lines       10835    10840       +5     
==========================================
- Hits         4759     4756       -3     
- Misses       5594     5601       +7     
- Partials      482      483       +1     
```

| Flag | Coverage Δ | |
|---|---|---|
| Object-compatibility-e2etests | `?` | |
| e2etests | `?` | |
| unittests | `43.87% <100.00%> (-0.05%)` | :arrow_down: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Impacted Files](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1470?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss) | Coverage Δ | |
|---|---|---|
| [pkg/dag/dag.go](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1470/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss#diff-cGtnL2RhZy9kYWcuZ28=) | `68.67% <100.00%> (+2.00%)` | :arrow_up: |
| [client/daemon/rpcserver/subscriber.go](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1470/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss#diff-Y2xpZW50L2RhZW1vbi9ycGNzZXJ2ZXIvc3Vic2NyaWJlci5nbw==) | `47.76% <0.00%> (-2.24%)` | :arrow_down: |
| [client/daemon/peer/peertask\_conductor.go](https://codecov.io/gh/dragonflyoss/Dragonfly2/pull/1470/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=dragonflyoss#diff-Y2xpZW50L2RhZW1vbi9wZWVyL3BlZXJ0YXNrX2NvbmR1Y3Rvci5nbw==) | `56.12% <0.00%> (-0.50%)` | :arrow_down: |


Patch:
diff --git a/pkg/dag/dag.go b/pkg/dag/dag.go
index 83567c57..96abd37e 100644
--- a/pkg/dag/dag.go
+++ b/pkg/dag/dag.go
@@ -51,6 +51,13 @@ type DAG interface {
 	// GetVertex gets vertex from graph.
 	GetVertex(id string) (*Vertex, error)
 
+	// LenVertex returns length of vertices.
+	LenVertex() int
+
+	// RangeVertex calls f sequentially for each key and value present in the vertices.
+	// If f returns false, range stops the iteration.
+	RangeVertex(fn func(key string, value *Vertex) bool)
+
 	// AddEdge adds edge between two vertices.
 	AddEdge(fromVertexID, toVertexID string) error
 
@@ -130,6 +137,24 @@ func (d *dag) GetVertex(id string) (*Vertex, error) {
 	return vertex, nil
 }
 
+// LenVertex returns length of vertices.
+func (d *dag) LenVertex() int {
+	return len(d.vertices)
+}
+
+// RangeVertex calls f sequentially for each key and value present in the vertices.
+// If f returns false, range stops the iteration.
+func (d *dag) RangeVertex(fn func(key string, value *Vertex) bool) {
+	d.mu.RLock()
+	defer d.mu.RUnlock()
+
+	for k, v := range d.vertices {
+		if !fn(k, v) {
+			break
+		}
+	}
+}
+
 // AddEdge adds edge between two vertices.
 func (d *dag) AddEdge(fromVertexID, toVertexID string) error {
 	d.mu.Lock()
diff --git a/pkg/dag/mocks/dag_mock.go b/pkg/dag/mocks/dag_mock.go
index f86ffac5..9cd3c2fd 100644
--- a/pkg/dag/mocks/dag_mock.go
+++ b/pkg/dag/mocks/dag_mock.go
@@ -102,3 +102,29 @@ func (mr *MockDAGMockRecorder) GetVertex(id interface{}) *gomock.Call {
 	mr.mock.ctrl.T.Helper()
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetVertex", reflect.TypeOf((*MockDAG)(nil).GetVertex), id)
 }
+
+// LenVertex mocks base method.
+func (m *MockDAG) LenVertex() int {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "LenVertex")
+	ret0, _ := ret[0].(int)
+	return ret0
+}
+
+// LenVertex indicates an expected call of LenVertex.
+func (mr *MockDAGMockRecorder) LenVertex() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LenVertex", reflect.TypeOf((*MockDAG)(nil).LenVertex))
+}
+
+// RangeVertex mocks base method.
+func (m *MockDAG) RangeVertex(fn func(string, *dag.Vertex) bool) {
+	m.ctrl.T.Helper()
+	m.ctrl.Call(m, "RangeVertex", fn)
+}
+
+// RangeVertex indicates an expected call of RangeVertex.
+func (mr *MockDAGMockRecorder) RangeVertex(fn interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RangeVertex", reflect.TypeOf((*MockDAG)(nil).RangeVertex), fn)
+}


Test patch:
diff --git a/pkg/dag/dag_test.go b/pkg/dag/dag_test.go
index de0bdf37..9590e6c9 100644
--- a/pkg/dag/dag_test.go
+++ b/pkg/dag/dag_test.go
@@ -164,6 +164,95 @@ func TestDAGGetVertex(t *testing.T) {
 	}
 }
 
+func TestDAGVertexLenVertex(t *testing.T) {
+	tests := []struct {
+		name   string
+		expect func(t *testing.T, d DAG)
+	}{
+		{
+			name: "get length of vertex",
+			expect: func(t *testing.T, d DAG) {
+				assert := assert.New(t)
+				if err := d.AddVertex(mockVertexID, mockVertexValue); err != nil {
+					assert.NoError(err)
+				}
+
+				d.LenVertex()
+				assert.Equal(d.LenVertex(), 1)
+
+				d.DeleteVertex(mockVertexID)
+				assert.Equal(d.LenVertex(), 0)
+			},
+		},
+		{
+			name: "empty dag",
+			expect: func(t *testing.T, d DAG) {
+				assert := assert.New(t)
+				assert.Equal(d.LenVertex(), 0)
+			},
+		},
+	}
+
+	for _, tc := range tests {
+		t.Run(tc.name, func(t *testing.T) {
+			d := NewDAG()
+			tc.expect(t, d)
+		})
+	}
+}
+
+func TestDAGRange(t *testing.T) {
+	tests := []struct {
+		name   string
+		expect func(t *testing.T, d DAG)
+	}{
+		{
+			name: "range vertices",
+			expect: func(t *testing.T, d DAG) {
+				assert := assert.New(t)
+				if err := d.AddVertex(mockVertexID, mockVertexValue); err != nil {
+					assert.NoError(err)
+				}
+
+				d.RangeVertex(func(k string, v *Vertex) bool {
+					assert.Equal(k, mockVertexID)
+					return true
+				})
+			},
+		},
+		{
+			name: "range failed",
+			expect: func(t *testing.T, d DAG) {
+				assert := assert.New(t)
+
+				var (
+					mockVertexEID = "bae"
+					mockVertexFID = "baf"
+				)
+				if err := d.AddVertex(mockVertexEID, mockVertexValue); err != nil {
+					assert.NoError(err)
+				}
+
+				if err := d.AddVertex(mockVertexFID, mockVertexValue); err != nil {
+					assert.NoError(err)
+				}
+
+				d.RangeVertex(func(k string, v *Vertex) bool {
+					assert.Contains([]string{mockVertexEID, mockVertexFID}, k)
+					return false
+				})
+			},
+		},
+	}
+
+	for _, tc := range tests {
+		t.Run(tc.name, func(t *testing.T) {
+			d := NewDAG()
+			tc.expect(t, d)
+		})
+	}
+}
+
 func TestDAGAddEdge(t *testing.T) {
 	tests := []struct {
 		name   string