key_index_test.go 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  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[reversion]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: reversion{5, 0},
  50. generations: []generation{{created: reversion{5, 0}, ver: 1, revs: []reversion{{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: reversion{7, 0},
  59. generations: []generation{{created: reversion{5, 0}, ver: 2, revs: []reversion{{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: reversion{7, 0},
  72. generations: []generation{{created: reversion{5, 0}, ver: 2, revs: []reversion{{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: reversion{15, 0},
  83. generations: []generation{
  84. {created: reversion{5, 0}, ver: 2, revs: []reversion{{main: 5}, {main: 7}}},
  85. {created: reversion{8, 0}, ver: 3, revs: []reversion{{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[reversion]struct{}
  98. }{
  99. {
  100. 1,
  101. &keyIndex{
  102. key: []byte("foo"),
  103. modified: reversion{12, 0},
  104. generations: []generation{
  105. {created: reversion{2, 0}, ver: 3, revs: []reversion{{main: 2}, {main: 4}, {main: 6}}},
  106. {created: reversion{8, 0}, ver: 3, revs: []reversion{{main: 8}, {main: 10}, {main: 12}}},
  107. {},
  108. },
  109. },
  110. map[reversion]struct{}{},
  111. },
  112. {
  113. 2,
  114. &keyIndex{
  115. key: []byte("foo"),
  116. modified: reversion{12, 0},
  117. generations: []generation{
  118. {created: reversion{2, 0}, ver: 3, revs: []reversion{{main: 2}, {main: 4}, {main: 6}}},
  119. {created: reversion{8, 0}, ver: 3, revs: []reversion{{main: 8}, {main: 10}, {main: 12}}},
  120. {},
  121. },
  122. },
  123. map[reversion]struct{}{
  124. reversion{main: 2}: struct{}{},
  125. },
  126. },
  127. {
  128. 3,
  129. &keyIndex{
  130. key: []byte("foo"),
  131. modified: reversion{12, 0},
  132. generations: []generation{
  133. {created: reversion{2, 0}, ver: 3, revs: []reversion{{main: 2}, {main: 4}, {main: 6}}},
  134. {created: reversion{8, 0}, ver: 3, revs: []reversion{{main: 8}, {main: 10}, {main: 12}}},
  135. {},
  136. },
  137. },
  138. map[reversion]struct{}{
  139. reversion{main: 2}: struct{}{},
  140. },
  141. },
  142. {
  143. 4,
  144. &keyIndex{
  145. key: []byte("foo"),
  146. modified: reversion{12, 0},
  147. generations: []generation{
  148. {created: reversion{2, 0}, ver: 3, revs: []reversion{{main: 4}, {main: 6}}},
  149. {created: reversion{8, 0}, ver: 3, revs: []reversion{{main: 8}, {main: 10}, {main: 12}}},
  150. {},
  151. },
  152. },
  153. map[reversion]struct{}{
  154. reversion{main: 4}: struct{}{},
  155. },
  156. },
  157. {
  158. 5,
  159. &keyIndex{
  160. key: []byte("foo"),
  161. modified: reversion{12, 0},
  162. generations: []generation{
  163. {created: reversion{2, 0}, ver: 3, revs: []reversion{{main: 4}, {main: 6}}},
  164. {created: reversion{8, 0}, ver: 3, revs: []reversion{{main: 8}, {main: 10}, {main: 12}}},
  165. {},
  166. },
  167. },
  168. map[reversion]struct{}{
  169. reversion{main: 4}: struct{}{},
  170. },
  171. },
  172. {
  173. 6,
  174. &keyIndex{
  175. key: []byte("foo"),
  176. modified: reversion{12, 0},
  177. generations: []generation{
  178. {created: reversion{8, 0}, ver: 3, revs: []reversion{{main: 8}, {main: 10}, {main: 12}}},
  179. {},
  180. },
  181. },
  182. map[reversion]struct{}{},
  183. },
  184. {
  185. 7,
  186. &keyIndex{
  187. key: []byte("foo"),
  188. modified: reversion{12, 0},
  189. generations: []generation{
  190. {created: reversion{8, 0}, ver: 3, revs: []reversion{{main: 8}, {main: 10}, {main: 12}}},
  191. {},
  192. },
  193. },
  194. map[reversion]struct{}{},
  195. },
  196. {
  197. 8,
  198. &keyIndex{
  199. key: []byte("foo"),
  200. modified: reversion{12, 0},
  201. generations: []generation{
  202. {created: reversion{8, 0}, ver: 3, revs: []reversion{{main: 8}, {main: 10}, {main: 12}}},
  203. {},
  204. },
  205. },
  206. map[reversion]struct{}{
  207. reversion{main: 8}: struct{}{},
  208. },
  209. },
  210. {
  211. 9,
  212. &keyIndex{
  213. key: []byte("foo"),
  214. modified: reversion{12, 0},
  215. generations: []generation{
  216. {created: reversion{8, 0}, ver: 3, revs: []reversion{{main: 8}, {main: 10}, {main: 12}}},
  217. {},
  218. },
  219. },
  220. map[reversion]struct{}{
  221. reversion{main: 8}: struct{}{},
  222. },
  223. },
  224. {
  225. 10,
  226. &keyIndex{
  227. key: []byte("foo"),
  228. modified: reversion{12, 0},
  229. generations: []generation{
  230. {created: reversion{8, 0}, ver: 3, revs: []reversion{{main: 10}, {main: 12}}},
  231. {},
  232. },
  233. },
  234. map[reversion]struct{}{
  235. reversion{main: 10}: struct{}{},
  236. },
  237. },
  238. {
  239. 11,
  240. &keyIndex{
  241. key: []byte("foo"),
  242. modified: reversion{12, 0},
  243. generations: []generation{
  244. {created: reversion{8, 0}, ver: 3, revs: []reversion{{main: 10}, {main: 12}}},
  245. {},
  246. },
  247. },
  248. map[reversion]struct{}{
  249. reversion{main: 10}: struct{}{},
  250. },
  251. },
  252. {
  253. 12,
  254. &keyIndex{
  255. key: []byte("foo"),
  256. modified: reversion{12, 0},
  257. generations: []generation{{}},
  258. },
  259. map[reversion]struct{}{},
  260. },
  261. }
  262. // Continous Compaction
  263. ki := newTestKeyIndex()
  264. for i, tt := range tests {
  265. am := make(map[reversion]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. // Jump Compaction
  275. for i, tt := range tests {
  276. if (i%2 == 0 && i < 6) && (i%2 == 1 && i > 6) {
  277. am := make(map[reversion]struct{})
  278. ki.compact(tt.compact, am)
  279. if !reflect.DeepEqual(ki, tt.wki) {
  280. t.Errorf("#%d: ki = %+v, want %+v", i, ki, tt.wki)
  281. }
  282. if !reflect.DeepEqual(am, tt.wam) {
  283. t.Errorf("#%d: am = %+v, want %+v", am, tt.wam)
  284. }
  285. }
  286. }
  287. // OnceCompaction
  288. for i, tt := range tests {
  289. ki := newTestKeyIndex()
  290. am := make(map[reversion]struct{})
  291. ki.compact(tt.compact, am)
  292. if !reflect.DeepEqual(ki, tt.wki) {
  293. t.Errorf("#%d: ki = %+v, want %+v", i, ki, tt.wki)
  294. }
  295. if !reflect.DeepEqual(am, tt.wam) {
  296. t.Errorf("#%d: am = %+v, want %+v", i, am, tt.wam)
  297. }
  298. }
  299. }
  300. func newTestKeyIndex() *keyIndex {
  301. // key: "foo"
  302. // rev: 12
  303. // generations:
  304. // {empty}
  305. // {8[1], 10[2], 12(t)[3]}
  306. // {2[1], 4[2], 6(t)[3]}
  307. ki := &keyIndex{key: []byte("foo")}
  308. ki.put(2, 0)
  309. ki.put(4, 0)
  310. ki.tombstone(6, 0)
  311. ki.put(8, 0)
  312. ki.put(10, 0)
  313. ki.tombstone(12, 0)
  314. return ki
  315. }