You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

redundancy_shrink_test.go 7.4 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. package ticktock
  2. import (
  3. "testing"
  4. . "github.com/smartystreets/goconvey/convey"
  5. "gitlink.org.cn/cloudream/common/pkgs/bitmap"
  6. "gitlink.org.cn/cloudream/jcs-pub/client/types"
  7. )
  8. func newTreeTest(nodeBlocksMap []bitmap.Bitmap64) combinatorialTree {
  9. tree := combinatorialTree{
  10. blocksMaps: make(map[int]bitmap.Bitmap64),
  11. stgIDToLocalStgID: make(map[types.UserSpaceID]int),
  12. }
  13. tree.nodes = make([]combinatorialTreeNode, (1 << len(nodeBlocksMap)))
  14. for id, mp := range nodeBlocksMap {
  15. tree.stgIDToLocalStgID[types.UserSpaceID(id)] = len(tree.localStgIDToStgID)
  16. tree.blocksMaps[len(tree.localStgIDToStgID)] = mp
  17. tree.localStgIDToStgID = append(tree.localStgIDToStgID, types.UserSpaceID(id))
  18. }
  19. tree.nodes[0].localHubID = -1
  20. index := 1
  21. tree.initNode(0, &tree.nodes[0], &index)
  22. return tree
  23. }
  24. func Test_iterCombBits(t *testing.T) {
  25. testcases := []struct {
  26. title string
  27. width int
  28. count int
  29. expectedValues []int
  30. }{
  31. {
  32. title: "1 of 4",
  33. width: 4,
  34. count: 1,
  35. expectedValues: []int{16, 8, 4, 2},
  36. },
  37. {
  38. title: "2 of 4",
  39. width: 4,
  40. count: 2,
  41. expectedValues: []int{24, 20, 18, 12, 10, 6},
  42. },
  43. {
  44. title: "3 of 4",
  45. width: 4,
  46. count: 3,
  47. expectedValues: []int{28, 26, 22, 14},
  48. },
  49. {
  50. title: "4 of 4",
  51. width: 4,
  52. count: 4,
  53. expectedValues: []int{30},
  54. },
  55. }
  56. for _, test := range testcases {
  57. Convey(test.title, t, func() {
  58. var ret []int
  59. var t combinatorialTree
  60. t.iterCombBits(test.width, test.count, 0, func(i int) {
  61. ret = append(ret, i)
  62. })
  63. So(ret, ShouldResemble, test.expectedValues)
  64. })
  65. }
  66. }
  67. func Test_newCombinatorialTree(t *testing.T) {
  68. testcases := []struct {
  69. title string
  70. nodeBlocks []bitmap.Bitmap64
  71. expectedTreeNodeLocalIDs []int
  72. expectedTreeNodeBitmaps []int
  73. }{
  74. {
  75. title: "1个节点",
  76. nodeBlocks: []bitmap.Bitmap64{1},
  77. expectedTreeNodeLocalIDs: []int{-1, 0},
  78. expectedTreeNodeBitmaps: []int{0, 1},
  79. },
  80. {
  81. title: "2个节点",
  82. nodeBlocks: []bitmap.Bitmap64{1, 0},
  83. expectedTreeNodeLocalIDs: []int{-1, 0, 1, 1},
  84. expectedTreeNodeBitmaps: []int{0, 1, 1, 0},
  85. },
  86. {
  87. title: "4个节点",
  88. nodeBlocks: []bitmap.Bitmap64{1, 2, 4, 8},
  89. expectedTreeNodeLocalIDs: []int{-1, 0, 1, 2, 3, 3, 2, 3, 3, 1, 2, 3, 3, 2, 3, 3},
  90. expectedTreeNodeBitmaps: []int{0, 1, 3, 7, 15, 11, 5, 13, 9, 2, 6, 14, 10, 4, 12, 8},
  91. },
  92. }
  93. for _, test := range testcases {
  94. Convey(test.title, t, func() {
  95. t := newTreeTest(test.nodeBlocks)
  96. var localIDs []int
  97. var bitmaps []int
  98. for _, n := range t.nodes {
  99. localIDs = append(localIDs, n.localHubID)
  100. bitmaps = append(bitmaps, int(n.blocksBitmap))
  101. }
  102. So(localIDs, ShouldResemble, test.expectedTreeNodeLocalIDs)
  103. So(bitmaps, ShouldResemble, test.expectedTreeNodeBitmaps)
  104. })
  105. }
  106. }
  107. func Test_UpdateBitmap(t *testing.T) {
  108. testcases := []struct {
  109. title string
  110. nodeBlocks []bitmap.Bitmap64
  111. updatedHubID types.UserSpaceID
  112. updatedBitmap bitmap.Bitmap64
  113. k int
  114. expectedTreeNodeBitmaps []int
  115. }{
  116. {
  117. title: "4个节点,更新但值不变",
  118. nodeBlocks: []bitmap.Bitmap64{1, 2, 4, 8},
  119. updatedHubID: types.UserSpaceID(0),
  120. updatedBitmap: bitmap.Bitmap64(1),
  121. k: 4,
  122. expectedTreeNodeBitmaps: []int{0, 1, 3, 7, 15, 11, 5, 13, 9, 2, 6, 14, 10, 4, 12, 8},
  123. },
  124. {
  125. title: "4个节点,更新0",
  126. nodeBlocks: []bitmap.Bitmap64{1, 2, 4, 8},
  127. updatedHubID: types.UserSpaceID(0),
  128. updatedBitmap: bitmap.Bitmap64(2),
  129. k: 4,
  130. expectedTreeNodeBitmaps: []int{0, 2, 2, 6, 14, 10, 6, 14, 10, 2, 6, 14, 10, 4, 12, 8},
  131. },
  132. {
  133. title: "4个节点,更新1",
  134. nodeBlocks: []bitmap.Bitmap64{1, 2, 4, 8},
  135. updatedHubID: types.UserSpaceID(1),
  136. updatedBitmap: bitmap.Bitmap64(1),
  137. k: 4,
  138. expectedTreeNodeBitmaps: []int{0, 1, 1, 5, 13, 9, 5, 13, 9, 1, 5, 13, 9, 4, 12, 8},
  139. },
  140. {
  141. title: "4个节点,更新2",
  142. nodeBlocks: []bitmap.Bitmap64{1, 2, 4, 8},
  143. updatedHubID: types.UserSpaceID(2),
  144. updatedBitmap: bitmap.Bitmap64(1),
  145. k: 4,
  146. expectedTreeNodeBitmaps: []int{0, 1, 3, 3, 11, 11, 1, 9, 9, 2, 3, 11, 10, 1, 9, 8},
  147. },
  148. {
  149. title: "4个节点,更新3",
  150. nodeBlocks: []bitmap.Bitmap64{1, 2, 4, 8},
  151. updatedHubID: types.UserSpaceID(3),
  152. updatedBitmap: bitmap.Bitmap64(1),
  153. k: 4,
  154. expectedTreeNodeBitmaps: []int{0, 1, 3, 7, 7, 3, 5, 5, 1, 2, 6, 7, 3, 4, 5, 1},
  155. },
  156. {
  157. title: "4个节点,k<4,更新0,0之前没有k个块,现在拥有",
  158. nodeBlocks: []bitmap.Bitmap64{1, 2, 4, 8},
  159. updatedHubID: types.UserSpaceID(0),
  160. updatedBitmap: bitmap.Bitmap64(3),
  161. k: 2,
  162. expectedTreeNodeBitmaps: []int{0, 3, 3, 7, 15, 11, 5, 13, 9, 2, 6, 14, 10, 4, 12, 8},
  163. },
  164. {
  165. title: "4个节点,k<4,更新0,0之前有k个块,现在没有",
  166. nodeBlocks: []bitmap.Bitmap64{3, 4, 0, 0},
  167. updatedHubID: types.UserSpaceID(0),
  168. updatedBitmap: bitmap.Bitmap64(0),
  169. k: 2,
  170. expectedTreeNodeBitmaps: []int{0, 0, 4, 4, 4, 4, 0, 0, 0, 4, 4, 4, 4, 0, 0, 0},
  171. },
  172. }
  173. for _, test := range testcases {
  174. Convey(test.title, t, func() {
  175. t := newTreeTest(test.nodeBlocks)
  176. t.UpdateBitmap(test.updatedHubID, test.updatedBitmap, test.k)
  177. var bitmaps []int
  178. for _, n := range t.nodes {
  179. bitmaps = append(bitmaps, int(n.blocksBitmap))
  180. }
  181. So(bitmaps, ShouldResemble, test.expectedTreeNodeBitmaps)
  182. })
  183. }
  184. }
  185. func Test_FindKBlocksMaxDepth(t *testing.T) {
  186. testcases := []struct {
  187. title string
  188. nodeBlocks []bitmap.Bitmap64
  189. k int
  190. expected int
  191. }{
  192. {
  193. title: "每个节点各有一个块",
  194. nodeBlocks: []bitmap.Bitmap64{1, 2, 4, 8},
  195. k: 2,
  196. expected: 2,
  197. },
  198. {
  199. title: "所有节点加起来块数不足",
  200. nodeBlocks: []bitmap.Bitmap64{1, 1, 1, 1},
  201. k: 2,
  202. expected: 4,
  203. },
  204. {
  205. title: "不同节点有相同块",
  206. nodeBlocks: []bitmap.Bitmap64{1, 1, 2, 4},
  207. k: 2,
  208. expected: 3,
  209. },
  210. {
  211. title: "一个节点就拥有所有块",
  212. nodeBlocks: []bitmap.Bitmap64{3, 6, 12, 24},
  213. k: 2,
  214. expected: 1,
  215. },
  216. {
  217. title: "只有一块,且只在某一个节点1",
  218. nodeBlocks: []bitmap.Bitmap64{1, 0},
  219. k: 1,
  220. expected: 2,
  221. },
  222. {
  223. title: "只有一块,且只在某一个节点2",
  224. nodeBlocks: []bitmap.Bitmap64{0, 1},
  225. k: 1,
  226. expected: 2,
  227. },
  228. }
  229. for _, test := range testcases {
  230. Convey(test.title, t, func() {
  231. t := newTreeTest(test.nodeBlocks)
  232. ret := t.FindKBlocksMaxDepth(test.k)
  233. So(ret, ShouldResemble, test.expected)
  234. })
  235. }
  236. }

本项目旨在将云际存储公共基础设施化,使个人及企业可低门槛使用高效的云际存储服务(安装开箱即用云际存储客户端即可,无需关注其他组件的部署),同时支持用户灵活便捷定制云际存储的功能细节。