key_index_test.go 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. package storage
  2. import (
  3. "reflect"
  4. "testing"
  5. )
  6. func TestKeyIndexGet(t *testing.T) {
  7. // key: "foo"
  8. // rev: 12
  9. // generations:
  10. // {empty}
  11. // {8[1], 10[2], 12(t)[3]}
  12. // {4[2], 6(t)[3]}
  13. ki := newTestKeyIndex()
  14. ki.compact(4, make(map[revision]struct{}))
  15. tests := []struct {
  16. rev int64
  17. wrev int64
  18. werr error
  19. }{
  20. {13, 12, nil},
  21. {13, 12, nil},
  22. // get on generation 2
  23. {12, 12, nil},
  24. {11, 10, nil},
  25. {10, 10, nil},
  26. {9, 8, nil},
  27. {8, 8, nil},
  28. {7, 6, nil},
  29. // get on generation 1
  30. {6, 6, nil},
  31. {5, 4, nil},
  32. {4, 4, nil},
  33. }
  34. for i, tt := range tests {
  35. rev, _, _, err := ki.get(tt.rev)
  36. if err != tt.werr {
  37. t.Errorf("#%d: err = %v, want %v", i, err, tt.werr)
  38. }
  39. if rev.main != tt.wrev {
  40. t.Errorf("#%d: rev = %d, want %d", i, rev.main, tt.rev)
  41. }
  42. }
  43. }
  44. func TestKeyIndexPut(t *testing.T) {
  45. ki := &keyIndex{key: []byte("foo")}
  46. ki.put(5, 0)
  47. wki := &keyIndex{
  48. key: []byte("foo"),
  49. modified: revision{5, 0},
  50. generations: []generation{{created: revision{5, 0}, ver: 1, revs: []revision{{main: 5}}}},
  51. }
  52. if !reflect.DeepEqual(ki, wki) {
  53. t.Errorf("ki = %+v, want %+v", ki, wki)
  54. }
  55. ki.put(7, 0)
  56. wki = &keyIndex{
  57. key: []byte("foo"),
  58. modified: revision{7, 0},
  59. generations: []generation{{created: revision{5, 0}, ver: 2, revs: []revision{{main: 5}, {main: 7}}}},
  60. }
  61. if !reflect.DeepEqual(ki, wki) {
  62. t.Errorf("ki = %+v, want %+v", ki, wki)
  63. }
  64. }
  65. func TestKeyIndexTombstone(t *testing.T) {
  66. ki := &keyIndex{key: []byte("foo")}
  67. ki.put(5, 0)
  68. ki.tombstone(7, 0)
  69. wki := &keyIndex{
  70. key: []byte("foo"),
  71. modified: revision{7, 0},
  72. generations: []generation{{created: revision{5, 0}, ver: 2, revs: []revision{{main: 5}, {main: 7}}}, {}},
  73. }
  74. if !reflect.DeepEqual(ki, wki) {
  75. t.Errorf("ki = %+v, want %+v", ki, wki)
  76. }
  77. ki.put(8, 0)
  78. ki.put(9, 0)
  79. ki.tombstone(15, 0)
  80. wki = &keyIndex{
  81. key: []byte("foo"),
  82. modified: revision{15, 0},
  83. generations: []generation{
  84. {created: revision{5, 0}, ver: 2, revs: []revision{{main: 5}, {main: 7}}},
  85. {created: revision{8, 0}, ver: 3, revs: []revision{{main: 8}, {main: 9}, {main: 15}}},
  86. {},
  87. },
  88. }
  89. if !reflect.DeepEqual(ki, wki) {
  90. t.Errorf("ki = %+v, want %+v", ki, wki)
  91. }
  92. }
  93. func TestKeyIndexCompact(t *testing.T) {
  94. tests := []struct {
  95. compact int64
  96. wki *keyIndex
  97. wam map[revision]struct{}
  98. }{
  99. {
  100. 1,
  101. &keyIndex{
  102. key: []byte("foo"),
  103. modified: revision{12, 0},
  104. generations: []generation{
  105. {created: revision{2, 0}, ver: 3, revs: []revision{{main: 2}, {main: 4}, {main: 6}}},
  106. {created: revision{8, 0}, ver: 3, revs: []revision{{main: 8}, {main: 10}, {main: 12}}},
  107. {},
  108. },
  109. },
  110. map[revision]struct{}{},
  111. },
  112. {
  113. 2,
  114. &keyIndex{
  115. key: []byte("foo"),
  116. modified: revision{12, 0},
  117. generations: []generation{
  118. {created: revision{2, 0}, ver: 3, revs: []revision{{main: 2}, {main: 4}, {main: 6}}},
  119. {created: revision{8, 0}, ver: 3, revs: []revision{{main: 8}, {main: 10}, {main: 12}}},
  120. {},
  121. },
  122. },
  123. map[revision]struct{}{
  124. revision{main: 2}: {},
  125. },
  126. },
  127. {
  128. 3,
  129. &keyIndex{
  130. key: []byte("foo"),
  131. modified: revision{12, 0},
  132. generations: []generation{
  133. {created: revision{2, 0}, ver: 3, revs: []revision{{main: 2}, {main: 4}, {main: 6}}},
  134. {created: revision{8, 0}, ver: 3, revs: []revision{{main: 8}, {main: 10}, {main: 12}}},
  135. {},
  136. },
  137. },
  138. map[revision]struct{}{
  139. revision{main: 2}: {},
  140. },
  141. },
  142. {
  143. 4,
  144. &keyIndex{
  145. key: []byte("foo"),
  146. modified: revision{12, 0},
  147. generations: []generation{
  148. {created: revision{2, 0}, ver: 3, revs: []revision{{main: 4}, {main: 6}}},
  149. {created: revision{8, 0}, ver: 3, revs: []revision{{main: 8}, {main: 10}, {main: 12}}},
  150. {},
  151. },
  152. },
  153. map[revision]struct{}{
  154. revision{main: 4}: {},
  155. },
  156. },
  157. {
  158. 5,
  159. &keyIndex{
  160. key: []byte("foo"),
  161. modified: revision{12, 0},
  162. generations: []generation{
  163. {created: revision{2, 0}, ver: 3, revs: []revision{{main: 4}, {main: 6}}},
  164. {created: revision{8, 0}, ver: 3, revs: []revision{{main: 8}, {main: 10}, {main: 12}}},
  165. {},
  166. },
  167. },
  168. map[revision]struct{}{
  169. revision{main: 4}: {},
  170. },
  171. },
  172. {
  173. 6,
  174. &keyIndex{
  175. key: []byte("foo"),
  176. modified: revision{12, 0},
  177. generations: []generation{
  178. {created: revision{8, 0}, ver: 3, revs: []revision{{main: 8}, {main: 10}, {main: 12}}},
  179. {},
  180. },
  181. },
  182. map[revision]struct{}{},
  183. },
  184. {
  185. 7,
  186. &keyIndex{
  187. key: []byte("foo"),
  188. modified: revision{12, 0},
  189. generations: []generation{
  190. {created: revision{8, 0}, ver: 3, revs: []revision{{main: 8}, {main: 10}, {main: 12}}},
  191. {},
  192. },
  193. },
  194. map[revision]struct{}{},
  195. },
  196. {
  197. 8,
  198. &keyIndex{
  199. key: []byte("foo"),
  200. modified: revision{12, 0},
  201. generations: []generation{
  202. {created: revision{8, 0}, ver: 3, revs: []revision{{main: 8}, {main: 10}, {main: 12}}},
  203. {},
  204. },
  205. },
  206. map[revision]struct{}{
  207. revision{main: 8}: {},
  208. },
  209. },
  210. {
  211. 9,
  212. &keyIndex{
  213. key: []byte("foo"),
  214. modified: revision{12, 0},
  215. generations: []generation{
  216. {created: revision{8, 0}, ver: 3, revs: []revision{{main: 8}, {main: 10}, {main: 12}}},
  217. {},
  218. },
  219. },
  220. map[revision]struct{}{
  221. revision{main: 8}: {},
  222. },
  223. },
  224. {
  225. 10,
  226. &keyIndex{
  227. key: []byte("foo"),
  228. modified: revision{12, 0},
  229. generations: []generation{
  230. {created: revision{8, 0}, ver: 3, revs: []revision{{main: 10}, {main: 12}}},
  231. {},
  232. },
  233. },
  234. map[revision]struct{}{
  235. revision{main: 10}: {},
  236. },
  237. },
  238. {
  239. 11,
  240. &keyIndex{
  241. key: []byte("foo"),
  242. modified: revision{12, 0},
  243. generations: []generation{
  244. {created: revision{8, 0}, ver: 3, revs: []revision{{main: 10}, {main: 12}}},
  245. {},
  246. },
  247. },
  248. map[revision]struct{}{
  249. revision{main: 10}: {},
  250. },
  251. },
  252. {
  253. 12,
  254. &keyIndex{
  255. key: []byte("foo"),
  256. modified: revision{12, 0},
  257. generations: []generation{{}},
  258. },
  259. map[revision]struct{}{},
  260. },
  261. }
  262. // Continous Compaction
  263. ki := newTestKeyIndex()
  264. for i, tt := range tests {
  265. am := make(map[revision]struct{})
  266. ki.compact(tt.compact, am)
  267. if !reflect.DeepEqual(ki, tt.wki) {
  268. t.Errorf("#%d: ki = %+v, want %+v", i, ki, tt.wki)
  269. }
  270. if !reflect.DeepEqual(am, tt.wam) {
  271. t.Errorf("#%d: am = %+v, want %+v", i, am, tt.wam)
  272. }
  273. }
  274. ki = newTestKeyIndex()
  275. // Jump Compaction
  276. for i, tt := range tests {
  277. if (i%2 == 0 && i < 6) || (i%2 == 1 && i > 6) {
  278. am := make(map[revision]struct{})
  279. ki.compact(tt.compact, am)
  280. if !reflect.DeepEqual(ki, tt.wki) {
  281. t.Errorf("#%d: ki = %+v, want %+v", i, ki, tt.wki)
  282. }
  283. if !reflect.DeepEqual(am, tt.wam) {
  284. t.Errorf("#%d: am = %+v, want %+v", i, am, tt.wam)
  285. }
  286. }
  287. }
  288. // OnceCompaction
  289. for i, tt := range tests {
  290. ki := newTestKeyIndex()
  291. am := make(map[revision]struct{})
  292. ki.compact(tt.compact, am)
  293. if !reflect.DeepEqual(ki, tt.wki) {
  294. t.Errorf("#%d: ki = %+v, want %+v", i, ki, tt.wki)
  295. }
  296. if !reflect.DeepEqual(am, tt.wam) {
  297. t.Errorf("#%d: am = %+v, want %+v", i, am, tt.wam)
  298. }
  299. }
  300. }
  301. func newTestKeyIndex() *keyIndex {
  302. // key: "foo"
  303. // rev: 12
  304. // generations:
  305. // {empty}
  306. // {8[1], 10[2], 12(t)[3]}
  307. // {2[1], 4[2], 6(t)[3]}
  308. ki := &keyIndex{key: []byte("foo")}
  309. ki.put(2, 0)
  310. ki.put(4, 0)
  311. ki.tombstone(6, 0)
  312. ki.put(8, 0)
  313. ki.put(10, 0)
  314. ki.tombstone(12, 0)
  315. return ki
  316. }