key_index_test.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  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, 0, ErrRevisionNotFound},
  21. {12, 0, ErrRevisionNotFound},
  22. // get on generation 2
  23. {11, 10, nil},
  24. {10, 10, nil},
  25. {9, 8, nil},
  26. {8, 8, nil},
  27. {7, 0, ErrRevisionNotFound},
  28. {6, 0, ErrRevisionNotFound},
  29. // get on generation 1
  30. {5, 4, nil},
  31. {4, 4, nil},
  32. {3, 0, ErrRevisionNotFound},
  33. {2, 0, ErrRevisionNotFound},
  34. {1, 0, ErrRevisionNotFound},
  35. {0, 0, ErrRevisionNotFound},
  36. }
  37. for i, tt := range tests {
  38. rev, _, _, err := ki.get(tt.rev)
  39. if err != tt.werr {
  40. t.Errorf("#%d: err = %v, want %v", i, err, tt.werr)
  41. }
  42. if rev.main != tt.wrev {
  43. t.Errorf("#%d: rev = %d, want %d", i, rev.main, tt.rev)
  44. }
  45. }
  46. }
  47. func TestKeyIndexPut(t *testing.T) {
  48. ki := &keyIndex{key: []byte("foo")}
  49. ki.put(5, 0)
  50. wki := &keyIndex{
  51. key: []byte("foo"),
  52. modified: revision{5, 0},
  53. generations: []generation{{created: revision{5, 0}, ver: 1, revs: []revision{{main: 5}}}},
  54. }
  55. if !reflect.DeepEqual(ki, wki) {
  56. t.Errorf("ki = %+v, want %+v", ki, wki)
  57. }
  58. ki.put(7, 0)
  59. wki = &keyIndex{
  60. key: []byte("foo"),
  61. modified: revision{7, 0},
  62. generations: []generation{{created: revision{5, 0}, ver: 2, revs: []revision{{main: 5}, {main: 7}}}},
  63. }
  64. if !reflect.DeepEqual(ki, wki) {
  65. t.Errorf("ki = %+v, want %+v", ki, wki)
  66. }
  67. }
  68. func TestKeyIndexRestore(t *testing.T) {
  69. ki := &keyIndex{key: []byte("foo")}
  70. ki.restore(revision{5, 0}, revision{7, 0}, 2)
  71. wki := &keyIndex{
  72. key: []byte("foo"),
  73. modified: revision{7, 0},
  74. generations: []generation{{created: revision{5, 0}, ver: 2, revs: []revision{{main: 7}}}},
  75. }
  76. if !reflect.DeepEqual(ki, wki) {
  77. t.Errorf("ki = %+v, want %+v", ki, wki)
  78. }
  79. }
  80. func TestKeyIndexTombstone(t *testing.T) {
  81. ki := &keyIndex{key: []byte("foo")}
  82. ki.put(5, 0)
  83. err := ki.tombstone(7, 0)
  84. if err != nil {
  85. t.Errorf("unexpected tombstone error: %v", err)
  86. }
  87. wki := &keyIndex{
  88. key: []byte("foo"),
  89. modified: revision{7, 0},
  90. generations: []generation{{created: revision{5, 0}, ver: 2, revs: []revision{{main: 5}, {main: 7}}}, {}},
  91. }
  92. if !reflect.DeepEqual(ki, wki) {
  93. t.Errorf("ki = %+v, want %+v", ki, wki)
  94. }
  95. ki.put(8, 0)
  96. ki.put(9, 0)
  97. err = ki.tombstone(15, 0)
  98. if err != nil {
  99. t.Errorf("unexpected tombstone error: %v", err)
  100. }
  101. wki = &keyIndex{
  102. key: []byte("foo"),
  103. modified: revision{15, 0},
  104. generations: []generation{
  105. {created: revision{5, 0}, ver: 2, revs: []revision{{main: 5}, {main: 7}}},
  106. {created: revision{8, 0}, ver: 3, revs: []revision{{main: 8}, {main: 9}, {main: 15}}},
  107. {},
  108. },
  109. }
  110. if !reflect.DeepEqual(ki, wki) {
  111. t.Errorf("ki = %+v, want %+v", ki, wki)
  112. }
  113. err = ki.tombstone(16, 0)
  114. if err != ErrRevisionNotFound {
  115. t.Errorf("tombstone error = %v, want %v", err, ErrRevisionNotFound)
  116. }
  117. }
  118. func TestKeyIndexCompact(t *testing.T) {
  119. tests := []struct {
  120. compact int64
  121. wki *keyIndex
  122. wam map[revision]struct{}
  123. }{
  124. {
  125. 1,
  126. &keyIndex{
  127. key: []byte("foo"),
  128. modified: revision{12, 0},
  129. generations: []generation{
  130. {created: revision{2, 0}, ver: 3, revs: []revision{{main: 2}, {main: 4}, {main: 6}}},
  131. {created: revision{8, 0}, ver: 3, revs: []revision{{main: 8}, {main: 10}, {main: 12}}},
  132. {},
  133. },
  134. },
  135. map[revision]struct{}{},
  136. },
  137. {
  138. 2,
  139. &keyIndex{
  140. key: []byte("foo"),
  141. modified: revision{12, 0},
  142. generations: []generation{
  143. {created: revision{2, 0}, ver: 3, revs: []revision{{main: 2}, {main: 4}, {main: 6}}},
  144. {created: revision{8, 0}, ver: 3, revs: []revision{{main: 8}, {main: 10}, {main: 12}}},
  145. {},
  146. },
  147. },
  148. map[revision]struct{}{
  149. revision{main: 2}: {},
  150. },
  151. },
  152. {
  153. 3,
  154. &keyIndex{
  155. key: []byte("foo"),
  156. modified: revision{12, 0},
  157. generations: []generation{
  158. {created: revision{2, 0}, ver: 3, revs: []revision{{main: 2}, {main: 4}, {main: 6}}},
  159. {created: revision{8, 0}, ver: 3, revs: []revision{{main: 8}, {main: 10}, {main: 12}}},
  160. {},
  161. },
  162. },
  163. map[revision]struct{}{
  164. revision{main: 2}: {},
  165. },
  166. },
  167. {
  168. 4,
  169. &keyIndex{
  170. key: []byte("foo"),
  171. modified: revision{12, 0},
  172. generations: []generation{
  173. {created: revision{2, 0}, ver: 3, revs: []revision{{main: 4}, {main: 6}}},
  174. {created: revision{8, 0}, ver: 3, revs: []revision{{main: 8}, {main: 10}, {main: 12}}},
  175. {},
  176. },
  177. },
  178. map[revision]struct{}{
  179. revision{main: 4}: {},
  180. },
  181. },
  182. {
  183. 5,
  184. &keyIndex{
  185. key: []byte("foo"),
  186. modified: revision{12, 0},
  187. generations: []generation{
  188. {created: revision{2, 0}, ver: 3, revs: []revision{{main: 4}, {main: 6}}},
  189. {created: revision{8, 0}, ver: 3, revs: []revision{{main: 8}, {main: 10}, {main: 12}}},
  190. {},
  191. },
  192. },
  193. map[revision]struct{}{
  194. revision{main: 4}: {},
  195. },
  196. },
  197. {
  198. 6,
  199. &keyIndex{
  200. key: []byte("foo"),
  201. modified: revision{12, 0},
  202. generations: []generation{
  203. {created: revision{8, 0}, ver: 3, revs: []revision{{main: 8}, {main: 10}, {main: 12}}},
  204. {},
  205. },
  206. },
  207. map[revision]struct{}{},
  208. },
  209. {
  210. 7,
  211. &keyIndex{
  212. key: []byte("foo"),
  213. modified: revision{12, 0},
  214. generations: []generation{
  215. {created: revision{8, 0}, ver: 3, revs: []revision{{main: 8}, {main: 10}, {main: 12}}},
  216. {},
  217. },
  218. },
  219. map[revision]struct{}{},
  220. },
  221. {
  222. 8,
  223. &keyIndex{
  224. key: []byte("foo"),
  225. modified: revision{12, 0},
  226. generations: []generation{
  227. {created: revision{8, 0}, ver: 3, revs: []revision{{main: 8}, {main: 10}, {main: 12}}},
  228. {},
  229. },
  230. },
  231. map[revision]struct{}{
  232. revision{main: 8}: {},
  233. },
  234. },
  235. {
  236. 9,
  237. &keyIndex{
  238. key: []byte("foo"),
  239. modified: revision{12, 0},
  240. generations: []generation{
  241. {created: revision{8, 0}, ver: 3, revs: []revision{{main: 8}, {main: 10}, {main: 12}}},
  242. {},
  243. },
  244. },
  245. map[revision]struct{}{
  246. revision{main: 8}: {},
  247. },
  248. },
  249. {
  250. 10,
  251. &keyIndex{
  252. key: []byte("foo"),
  253. modified: revision{12, 0},
  254. generations: []generation{
  255. {created: revision{8, 0}, ver: 3, revs: []revision{{main: 10}, {main: 12}}},
  256. {},
  257. },
  258. },
  259. map[revision]struct{}{
  260. revision{main: 10}: {},
  261. },
  262. },
  263. {
  264. 11,
  265. &keyIndex{
  266. key: []byte("foo"),
  267. modified: revision{12, 0},
  268. generations: []generation{
  269. {created: revision{8, 0}, ver: 3, revs: []revision{{main: 10}, {main: 12}}},
  270. {},
  271. },
  272. },
  273. map[revision]struct{}{
  274. revision{main: 10}: {},
  275. },
  276. },
  277. {
  278. 12,
  279. &keyIndex{
  280. key: []byte("foo"),
  281. modified: revision{12, 0},
  282. generations: []generation{{}},
  283. },
  284. map[revision]struct{}{},
  285. },
  286. }
  287. // Continous Compaction
  288. ki := newTestKeyIndex()
  289. for i, tt := range tests {
  290. am := make(map[revision]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. // Jump Compaction
  300. ki = newTestKeyIndex()
  301. for i, tt := range tests {
  302. if (i%2 == 0 && i < 6) || (i%2 == 1 && i > 6) {
  303. am := make(map[revision]struct{})
  304. ki.compact(tt.compact, am)
  305. if !reflect.DeepEqual(ki, tt.wki) {
  306. t.Errorf("#%d: ki = %+v, want %+v", i, ki, tt.wki)
  307. }
  308. if !reflect.DeepEqual(am, tt.wam) {
  309. t.Errorf("#%d: am = %+v, want %+v", i, am, tt.wam)
  310. }
  311. }
  312. }
  313. // Once Compaction
  314. for i, tt := range tests {
  315. ki := newTestKeyIndex()
  316. am := make(map[revision]struct{})
  317. ki.compact(tt.compact, am)
  318. if !reflect.DeepEqual(ki, tt.wki) {
  319. t.Errorf("#%d: ki = %+v, want %+v", i, ki, tt.wki)
  320. }
  321. if !reflect.DeepEqual(am, tt.wam) {
  322. t.Errorf("#%d: am = %+v, want %+v", i, am, tt.wam)
  323. }
  324. }
  325. }
  326. // test that compact on version that higher than last modified version works well
  327. func TestKeyIndexCompactOnFurtherRev(t *testing.T) {
  328. ki := &keyIndex{key: []byte("foo")}
  329. ki.put(1, 0)
  330. ki.put(2, 0)
  331. am := make(map[revision]struct{})
  332. ki.compact(3, am)
  333. wki := &keyIndex{
  334. key: []byte("foo"),
  335. modified: revision{2, 0},
  336. generations: []generation{
  337. {created: revision{1, 0}, ver: 2, revs: []revision{{main: 2}}},
  338. },
  339. }
  340. wam := map[revision]struct{}{
  341. revision{main: 2}: {},
  342. }
  343. if !reflect.DeepEqual(ki, wki) {
  344. t.Errorf("ki = %+v, want %+v", ki, wki)
  345. }
  346. if !reflect.DeepEqual(am, wam) {
  347. t.Errorf("am = %+v, want %+v", am, wam)
  348. }
  349. }
  350. func TestKeyIndexIsEmpty(t *testing.T) {
  351. tests := []struct {
  352. ki *keyIndex
  353. w bool
  354. }{
  355. {
  356. &keyIndex{
  357. key: []byte("foo"),
  358. generations: []generation{{}},
  359. },
  360. true,
  361. },
  362. {
  363. &keyIndex{
  364. key: []byte("foo"),
  365. modified: revision{2, 0},
  366. generations: []generation{
  367. {created: revision{1, 0}, ver: 2, revs: []revision{{main: 2}}},
  368. },
  369. },
  370. false,
  371. },
  372. }
  373. for i, tt := range tests {
  374. g := tt.ki.isEmpty()
  375. if g != tt.w {
  376. t.Errorf("#%d: isEmpty = %v, want %v", i, g, tt.w)
  377. }
  378. }
  379. }
  380. func TestKeyIndexFindGeneration(t *testing.T) {
  381. ki := newTestKeyIndex()
  382. tests := []struct {
  383. rev int64
  384. wg *generation
  385. }{
  386. {0, nil},
  387. {1, nil},
  388. {2, &ki.generations[0]},
  389. {3, &ki.generations[0]},
  390. {4, &ki.generations[0]},
  391. {5, &ki.generations[0]},
  392. {6, nil},
  393. {7, nil},
  394. {8, &ki.generations[1]},
  395. {9, &ki.generations[1]},
  396. {10, &ki.generations[1]},
  397. {11, &ki.generations[1]},
  398. {12, nil},
  399. {13, nil},
  400. }
  401. for i, tt := range tests {
  402. g := ki.findGeneration(tt.rev)
  403. if g != tt.wg {
  404. t.Errorf("#%d: generation = %+v, want %+v", i, g, tt.wg)
  405. }
  406. }
  407. }
  408. func TestKeyIndexLess(t *testing.T) {
  409. ki := &keyIndex{key: []byte("foo")}
  410. tests := []struct {
  411. ki *keyIndex
  412. w bool
  413. }{
  414. {&keyIndex{key: []byte("doo")}, false},
  415. {&keyIndex{key: []byte("foo")}, false},
  416. {&keyIndex{key: []byte("goo")}, true},
  417. }
  418. for i, tt := range tests {
  419. g := ki.Less(tt.ki)
  420. if g != tt.w {
  421. t.Errorf("#%d: Less = %v, want %v", i, g, tt.w)
  422. }
  423. }
  424. }
  425. func TestGenerationIsEmpty(t *testing.T) {
  426. tests := []struct {
  427. g *generation
  428. w bool
  429. }{
  430. {nil, true},
  431. {&generation{}, true},
  432. {&generation{revs: []revision{{main: 1}}}, false},
  433. }
  434. for i, tt := range tests {
  435. g := tt.g.isEmpty()
  436. if g != tt.w {
  437. t.Errorf("#%d: isEmpty = %v, want %v", i, g, tt.w)
  438. }
  439. }
  440. }
  441. func TestGenerationWalk(t *testing.T) {
  442. g := &generation{
  443. ver: 3,
  444. created: revision{2, 0},
  445. revs: []revision{{main: 2}, {main: 4}, {main: 6}},
  446. }
  447. tests := []struct {
  448. f func(rev revision) bool
  449. wi int
  450. }{
  451. {func(rev revision) bool { return rev.main >= 7 }, 2},
  452. {func(rev revision) bool { return rev.main >= 6 }, 1},
  453. {func(rev revision) bool { return rev.main >= 5 }, 1},
  454. {func(rev revision) bool { return rev.main >= 4 }, 0},
  455. {func(rev revision) bool { return rev.main >= 3 }, 0},
  456. {func(rev revision) bool { return rev.main >= 2 }, -1},
  457. }
  458. for i, tt := range tests {
  459. idx := g.walk(tt.f)
  460. if idx != tt.wi {
  461. t.Errorf("#%d: index = %d, want %d", i, idx, tt.wi)
  462. }
  463. }
  464. }
  465. func newTestKeyIndex() *keyIndex {
  466. // key: "foo"
  467. // rev: 12
  468. // generations:
  469. // {empty}
  470. // {8[1], 10[2], 12(t)[3]}
  471. // {2[1], 4[2], 6(t)[3]}
  472. ki := &keyIndex{key: []byte("foo")}
  473. ki.put(2, 0)
  474. ki.put(4, 0)
  475. ki.tombstone(6, 0)
  476. ki.put(8, 0)
  477. ki.put(10, 0)
  478. ki.tombstone(12, 0)
  479. return ki
  480. }