|
- package ticktock
-
- import (
- "testing"
-
- . "github.com/smartystreets/goconvey/convey"
- "gitlink.org.cn/cloudream/common/pkgs/bitmap"
- "gitlink.org.cn/cloudream/jcs-pub/client/types"
- )
-
- func newTreeTest(nodeBlocksMap []bitmap.Bitmap64) combinatorialTree {
- tree := combinatorialTree{
- blocksMaps: make(map[int]bitmap.Bitmap64),
- stgIDToLocalStgID: make(map[types.UserSpaceID]int),
- }
-
- tree.nodes = make([]combinatorialTreeNode, (1 << len(nodeBlocksMap)))
- for id, mp := range nodeBlocksMap {
- tree.stgIDToLocalStgID[types.UserSpaceID(id)] = len(tree.localStgIDToStgID)
- tree.blocksMaps[len(tree.localStgIDToStgID)] = mp
- tree.localStgIDToStgID = append(tree.localStgIDToStgID, types.UserSpaceID(id))
- }
-
- tree.nodes[0].localHubID = -1
- index := 1
- tree.initNode(0, &tree.nodes[0], &index)
-
- return tree
- }
-
- func Test_iterCombBits(t *testing.T) {
- testcases := []struct {
- title string
- width int
- count int
- expectedValues []int
- }{
- {
- title: "1 of 4",
- width: 4,
- count: 1,
- expectedValues: []int{16, 8, 4, 2},
- },
-
- {
- title: "2 of 4",
- width: 4,
- count: 2,
- expectedValues: []int{24, 20, 18, 12, 10, 6},
- },
-
- {
- title: "3 of 4",
- width: 4,
- count: 3,
- expectedValues: []int{28, 26, 22, 14},
- },
-
- {
- title: "4 of 4",
- width: 4,
- count: 4,
- expectedValues: []int{30},
- },
- }
-
- for _, test := range testcases {
- Convey(test.title, t, func() {
- var ret []int
- var t combinatorialTree
- t.iterCombBits(test.width, test.count, 0, func(i int) {
- ret = append(ret, i)
- })
-
- So(ret, ShouldResemble, test.expectedValues)
- })
- }
- }
-
- func Test_newCombinatorialTree(t *testing.T) {
- testcases := []struct {
- title string
- nodeBlocks []bitmap.Bitmap64
- expectedTreeNodeLocalIDs []int
- expectedTreeNodeBitmaps []int
- }{
- {
- title: "1个节点",
- nodeBlocks: []bitmap.Bitmap64{1},
- expectedTreeNodeLocalIDs: []int{-1, 0},
- expectedTreeNodeBitmaps: []int{0, 1},
- },
- {
- title: "2个节点",
- nodeBlocks: []bitmap.Bitmap64{1, 0},
- expectedTreeNodeLocalIDs: []int{-1, 0, 1, 1},
- expectedTreeNodeBitmaps: []int{0, 1, 1, 0},
- },
- {
- title: "4个节点",
- nodeBlocks: []bitmap.Bitmap64{1, 2, 4, 8},
- expectedTreeNodeLocalIDs: []int{-1, 0, 1, 2, 3, 3, 2, 3, 3, 1, 2, 3, 3, 2, 3, 3},
- expectedTreeNodeBitmaps: []int{0, 1, 3, 7, 15, 11, 5, 13, 9, 2, 6, 14, 10, 4, 12, 8},
- },
- }
-
- for _, test := range testcases {
- Convey(test.title, t, func() {
- t := newTreeTest(test.nodeBlocks)
-
- var localIDs []int
- var bitmaps []int
- for _, n := range t.nodes {
- localIDs = append(localIDs, n.localHubID)
- bitmaps = append(bitmaps, int(n.blocksBitmap))
- }
-
- So(localIDs, ShouldResemble, test.expectedTreeNodeLocalIDs)
- So(bitmaps, ShouldResemble, test.expectedTreeNodeBitmaps)
- })
- }
- }
-
- func Test_UpdateBitmap(t *testing.T) {
- testcases := []struct {
- title string
- nodeBlocks []bitmap.Bitmap64
- updatedHubID types.UserSpaceID
- updatedBitmap bitmap.Bitmap64
- k int
- expectedTreeNodeBitmaps []int
- }{
-
- {
- title: "4个节点,更新但值不变",
- nodeBlocks: []bitmap.Bitmap64{1, 2, 4, 8},
- updatedHubID: types.UserSpaceID(0),
- updatedBitmap: bitmap.Bitmap64(1),
- k: 4,
- expectedTreeNodeBitmaps: []int{0, 1, 3, 7, 15, 11, 5, 13, 9, 2, 6, 14, 10, 4, 12, 8},
- },
-
- {
- title: "4个节点,更新0",
- nodeBlocks: []bitmap.Bitmap64{1, 2, 4, 8},
- updatedHubID: types.UserSpaceID(0),
- updatedBitmap: bitmap.Bitmap64(2),
- k: 4,
- expectedTreeNodeBitmaps: []int{0, 2, 2, 6, 14, 10, 6, 14, 10, 2, 6, 14, 10, 4, 12, 8},
- },
-
- {
- title: "4个节点,更新1",
- nodeBlocks: []bitmap.Bitmap64{1, 2, 4, 8},
- updatedHubID: types.UserSpaceID(1),
- updatedBitmap: bitmap.Bitmap64(1),
- k: 4,
- expectedTreeNodeBitmaps: []int{0, 1, 1, 5, 13, 9, 5, 13, 9, 1, 5, 13, 9, 4, 12, 8},
- },
-
- {
- title: "4个节点,更新2",
- nodeBlocks: []bitmap.Bitmap64{1, 2, 4, 8},
- updatedHubID: types.UserSpaceID(2),
- updatedBitmap: bitmap.Bitmap64(1),
- k: 4,
- expectedTreeNodeBitmaps: []int{0, 1, 3, 3, 11, 11, 1, 9, 9, 2, 3, 11, 10, 1, 9, 8},
- },
-
- {
- title: "4个节点,更新3",
- nodeBlocks: []bitmap.Bitmap64{1, 2, 4, 8},
- updatedHubID: types.UserSpaceID(3),
- updatedBitmap: bitmap.Bitmap64(1),
- k: 4,
- expectedTreeNodeBitmaps: []int{0, 1, 3, 7, 7, 3, 5, 5, 1, 2, 6, 7, 3, 4, 5, 1},
- },
-
- {
- title: "4个节点,k<4,更新0,0之前没有k个块,现在拥有",
- nodeBlocks: []bitmap.Bitmap64{1, 2, 4, 8},
- updatedHubID: types.UserSpaceID(0),
- updatedBitmap: bitmap.Bitmap64(3),
- k: 2,
- expectedTreeNodeBitmaps: []int{0, 3, 3, 7, 15, 11, 5, 13, 9, 2, 6, 14, 10, 4, 12, 8},
- },
- {
- title: "4个节点,k<4,更新0,0之前有k个块,现在没有",
- nodeBlocks: []bitmap.Bitmap64{3, 4, 0, 0},
- updatedHubID: types.UserSpaceID(0),
- updatedBitmap: bitmap.Bitmap64(0),
- k: 2,
- expectedTreeNodeBitmaps: []int{0, 0, 4, 4, 4, 4, 0, 0, 0, 4, 4, 4, 4, 0, 0, 0},
- },
- }
-
- for _, test := range testcases {
- Convey(test.title, t, func() {
- t := newTreeTest(test.nodeBlocks)
- t.UpdateBitmap(test.updatedHubID, test.updatedBitmap, test.k)
-
- var bitmaps []int
- for _, n := range t.nodes {
- bitmaps = append(bitmaps, int(n.blocksBitmap))
- }
-
- So(bitmaps, ShouldResemble, test.expectedTreeNodeBitmaps)
- })
- }
- }
-
- func Test_FindKBlocksMaxDepth(t *testing.T) {
- testcases := []struct {
- title string
- nodeBlocks []bitmap.Bitmap64
- k int
- expected int
- }{
- {
- title: "每个节点各有一个块",
- nodeBlocks: []bitmap.Bitmap64{1, 2, 4, 8},
- k: 2,
- expected: 2,
- },
- {
- title: "所有节点加起来块数不足",
- nodeBlocks: []bitmap.Bitmap64{1, 1, 1, 1},
- k: 2,
- expected: 4,
- },
- {
- title: "不同节点有相同块",
- nodeBlocks: []bitmap.Bitmap64{1, 1, 2, 4},
- k: 2,
- expected: 3,
- },
- {
- title: "一个节点就拥有所有块",
- nodeBlocks: []bitmap.Bitmap64{3, 6, 12, 24},
- k: 2,
- expected: 1,
- },
- {
- title: "只有一块,且只在某一个节点1",
- nodeBlocks: []bitmap.Bitmap64{1, 0},
- k: 1,
- expected: 2,
- },
- {
- title: "只有一块,且只在某一个节点2",
- nodeBlocks: []bitmap.Bitmap64{0, 1},
- k: 1,
- expected: 2,
- },
- }
-
- for _, test := range testcases {
- Convey(test.title, t, func() {
- t := newTreeTest(test.nodeBlocks)
- ret := t.FindKBlocksMaxDepth(test.k)
- So(ret, ShouldResemble, test.expected)
- })
- }
- }
|