key_index_test.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
  1. // Copyright 2015 The etcd Authors
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package mvcc
  15. import (
  16. "reflect"
  17. "testing"
  18. "go.uber.org/zap"
  19. )
  20. func TestKeyIndexGet(t *testing.T) {
  21. // key: "foo"
  22. // rev: 16
  23. // generations:
  24. // {empty}
  25. // {{14, 0}[1], {14, 1}[2], {16, 0}(t)[3]}
  26. // {{8, 0}[1], {10, 0}[2], {12, 0}(t)[3]}
  27. // {{2, 0}[1], {4, 0}[2], {6, 0}(t)[3]}
  28. ki := newTestKeyIndex()
  29. ki.compact(zap.NewExample(), 4, make(map[revision]struct{}))
  30. tests := []struct {
  31. rev int64
  32. wmod revision
  33. wcreat revision
  34. wver int64
  35. werr error
  36. }{
  37. {17, revision{}, revision{}, 0, ErrRevisionNotFound},
  38. {16, revision{}, revision{}, 0, ErrRevisionNotFound},
  39. // get on generation 3
  40. {15, revision{14, 1}, revision{14, 0}, 2, nil},
  41. {14, revision{14, 1}, revision{14, 0}, 2, nil},
  42. {13, revision{}, revision{}, 0, ErrRevisionNotFound},
  43. {12, revision{}, revision{}, 0, ErrRevisionNotFound},
  44. // get on generation 2
  45. {11, revision{10, 0}, revision{8, 0}, 2, nil},
  46. {10, revision{10, 0}, revision{8, 0}, 2, nil},
  47. {9, revision{8, 0}, revision{8, 0}, 1, nil},
  48. {8, revision{8, 0}, revision{8, 0}, 1, nil},
  49. {7, revision{}, revision{}, 0, ErrRevisionNotFound},
  50. {6, revision{}, revision{}, 0, ErrRevisionNotFound},
  51. // get on generation 1
  52. {5, revision{4, 0}, revision{2, 0}, 2, nil},
  53. {4, revision{4, 0}, revision{2, 0}, 2, nil},
  54. {3, revision{}, revision{}, 0, ErrRevisionNotFound},
  55. {2, revision{}, revision{}, 0, ErrRevisionNotFound},
  56. {1, revision{}, revision{}, 0, ErrRevisionNotFound},
  57. {0, revision{}, revision{}, 0, ErrRevisionNotFound},
  58. }
  59. for i, tt := range tests {
  60. mod, creat, ver, err := ki.get(zap.NewExample(), tt.rev)
  61. if err != tt.werr {
  62. t.Errorf("#%d: err = %v, want %v", i, err, tt.werr)
  63. }
  64. if mod != tt.wmod {
  65. t.Errorf("#%d: modified = %+v, want %+v", i, mod, tt.wmod)
  66. }
  67. if creat != tt.wcreat {
  68. t.Errorf("#%d: created = %+v, want %+v", i, creat, tt.wcreat)
  69. }
  70. if ver != tt.wver {
  71. t.Errorf("#%d: version = %d, want %d", i, ver, tt.wver)
  72. }
  73. }
  74. }
  75. func TestKeyIndexSince(t *testing.T) {
  76. ki := newTestKeyIndex()
  77. ki.compact(zap.NewExample(), 4, make(map[revision]struct{}))
  78. allRevs := []revision{{4, 0}, {6, 0}, {8, 0}, {10, 0}, {12, 0}, {14, 1}, {16, 0}}
  79. tests := []struct {
  80. rev int64
  81. wrevs []revision
  82. }{
  83. {17, nil},
  84. {16, allRevs[6:]},
  85. {15, allRevs[6:]},
  86. {14, allRevs[5:]},
  87. {13, allRevs[5:]},
  88. {12, allRevs[4:]},
  89. {11, allRevs[4:]},
  90. {10, allRevs[3:]},
  91. {9, allRevs[3:]},
  92. {8, allRevs[2:]},
  93. {7, allRevs[2:]},
  94. {6, allRevs[1:]},
  95. {5, allRevs[1:]},
  96. {4, allRevs},
  97. {3, allRevs},
  98. {2, allRevs},
  99. {1, allRevs},
  100. {0, allRevs},
  101. }
  102. for i, tt := range tests {
  103. revs := ki.since(zap.NewExample(), tt.rev)
  104. if !reflect.DeepEqual(revs, tt.wrevs) {
  105. t.Errorf("#%d: revs = %+v, want %+v", i, revs, tt.wrevs)
  106. }
  107. }
  108. }
  109. func TestKeyIndexPut(t *testing.T) {
  110. ki := &keyIndex{key: []byte("foo")}
  111. ki.put(zap.NewExample(), 5, 0)
  112. wki := &keyIndex{
  113. key: []byte("foo"),
  114. modified: revision{5, 0},
  115. generations: []generation{{created: revision{5, 0}, ver: 1, revs: []revision{{main: 5}}}},
  116. }
  117. if !reflect.DeepEqual(ki, wki) {
  118. t.Errorf("ki = %+v, want %+v", ki, wki)
  119. }
  120. ki.put(zap.NewExample(), 7, 0)
  121. wki = &keyIndex{
  122. key: []byte("foo"),
  123. modified: revision{7, 0},
  124. generations: []generation{{created: revision{5, 0}, ver: 2, revs: []revision{{main: 5}, {main: 7}}}},
  125. }
  126. if !reflect.DeepEqual(ki, wki) {
  127. t.Errorf("ki = %+v, want %+v", ki, wki)
  128. }
  129. }
  130. func TestKeyIndexRestore(t *testing.T) {
  131. ki := &keyIndex{key: []byte("foo")}
  132. ki.restore(zap.NewExample(), revision{5, 0}, revision{7, 0}, 2)
  133. wki := &keyIndex{
  134. key: []byte("foo"),
  135. modified: revision{7, 0},
  136. generations: []generation{{created: revision{5, 0}, ver: 2, revs: []revision{{main: 7}}}},
  137. }
  138. if !reflect.DeepEqual(ki, wki) {
  139. t.Errorf("ki = %+v, want %+v", ki, wki)
  140. }
  141. }
  142. func TestKeyIndexTombstone(t *testing.T) {
  143. ki := &keyIndex{key: []byte("foo")}
  144. ki.put(zap.NewExample(), 5, 0)
  145. err := ki.tombstone(zap.NewExample(), 7, 0)
  146. if err != nil {
  147. t.Errorf("unexpected tombstone error: %v", err)
  148. }
  149. wki := &keyIndex{
  150. key: []byte("foo"),
  151. modified: revision{7, 0},
  152. generations: []generation{{created: revision{5, 0}, ver: 2, revs: []revision{{main: 5}, {main: 7}}}, {}},
  153. }
  154. if !reflect.DeepEqual(ki, wki) {
  155. t.Errorf("ki = %+v, want %+v", ki, wki)
  156. }
  157. ki.put(zap.NewExample(), 8, 0)
  158. ki.put(zap.NewExample(), 9, 0)
  159. err = ki.tombstone(zap.NewExample(), 15, 0)
  160. if err != nil {
  161. t.Errorf("unexpected tombstone error: %v", err)
  162. }
  163. wki = &keyIndex{
  164. key: []byte("foo"),
  165. modified: revision{15, 0},
  166. generations: []generation{
  167. {created: revision{5, 0}, ver: 2, revs: []revision{{main: 5}, {main: 7}}},
  168. {created: revision{8, 0}, ver: 3, revs: []revision{{main: 8}, {main: 9}, {main: 15}}},
  169. {},
  170. },
  171. }
  172. if !reflect.DeepEqual(ki, wki) {
  173. t.Errorf("ki = %+v, want %+v", ki, wki)
  174. }
  175. err = ki.tombstone(zap.NewExample(), 16, 0)
  176. if err != ErrRevisionNotFound {
  177. t.Errorf("tombstone error = %v, want %v", err, ErrRevisionNotFound)
  178. }
  179. }
  180. func TestKeyIndexCompactAndKeep(t *testing.T) {
  181. tests := []struct {
  182. compact int64
  183. wki *keyIndex
  184. wam map[revision]struct{}
  185. }{
  186. {
  187. 1,
  188. &keyIndex{
  189. key: []byte("foo"),
  190. modified: revision{16, 0},
  191. generations: []generation{
  192. {created: revision{2, 0}, ver: 3, revs: []revision{{main: 2}, {main: 4}, {main: 6}}},
  193. {created: revision{8, 0}, ver: 3, revs: []revision{{main: 8}, {main: 10}, {main: 12}}},
  194. {created: revision{14, 0}, ver: 3, revs: []revision{{main: 14}, {main: 14, sub: 1}, {main: 16}}},
  195. {},
  196. },
  197. },
  198. map[revision]struct{}{},
  199. },
  200. {
  201. 2,
  202. &keyIndex{
  203. key: []byte("foo"),
  204. modified: revision{16, 0},
  205. generations: []generation{
  206. {created: revision{2, 0}, ver: 3, revs: []revision{{main: 2}, {main: 4}, {main: 6}}},
  207. {created: revision{8, 0}, ver: 3, revs: []revision{{main: 8}, {main: 10}, {main: 12}}},
  208. {created: revision{14, 0}, ver: 3, revs: []revision{{main: 14}, {main: 14, sub: 1}, {main: 16}}},
  209. {},
  210. },
  211. },
  212. map[revision]struct{}{
  213. {main: 2}: {},
  214. },
  215. },
  216. {
  217. 3,
  218. &keyIndex{
  219. key: []byte("foo"),
  220. modified: revision{16, 0},
  221. generations: []generation{
  222. {created: revision{2, 0}, ver: 3, revs: []revision{{main: 2}, {main: 4}, {main: 6}}},
  223. {created: revision{8, 0}, ver: 3, revs: []revision{{main: 8}, {main: 10}, {main: 12}}},
  224. {created: revision{14, 0}, ver: 3, revs: []revision{{main: 14}, {main: 14, sub: 1}, {main: 16}}},
  225. {},
  226. },
  227. },
  228. map[revision]struct{}{
  229. {main: 2}: {},
  230. },
  231. },
  232. {
  233. 4,
  234. &keyIndex{
  235. key: []byte("foo"),
  236. modified: revision{16, 0},
  237. generations: []generation{
  238. {created: revision{2, 0}, ver: 3, revs: []revision{{main: 4}, {main: 6}}},
  239. {created: revision{8, 0}, ver: 3, revs: []revision{{main: 8}, {main: 10}, {main: 12}}},
  240. {created: revision{14, 0}, ver: 3, revs: []revision{{main: 14}, {main: 14, sub: 1}, {main: 16}}},
  241. {},
  242. },
  243. },
  244. map[revision]struct{}{
  245. {main: 4}: {},
  246. },
  247. },
  248. {
  249. 5,
  250. &keyIndex{
  251. key: []byte("foo"),
  252. modified: revision{16, 0},
  253. generations: []generation{
  254. {created: revision{2, 0}, ver: 3, revs: []revision{{main: 4}, {main: 6}}},
  255. {created: revision{8, 0}, ver: 3, revs: []revision{{main: 8}, {main: 10}, {main: 12}}},
  256. {created: revision{14, 0}, ver: 3, revs: []revision{{main: 14}, {main: 14, sub: 1}, {main: 16}}},
  257. {},
  258. },
  259. },
  260. map[revision]struct{}{
  261. {main: 4}: {},
  262. },
  263. },
  264. {
  265. 6,
  266. &keyIndex{
  267. key: []byte("foo"),
  268. modified: revision{16, 0},
  269. generations: []generation{
  270. {created: revision{8, 0}, ver: 3, revs: []revision{{main: 8}, {main: 10}, {main: 12}}},
  271. {created: revision{14, 0}, ver: 3, revs: []revision{{main: 14}, {main: 14, sub: 1}, {main: 16}}},
  272. {},
  273. },
  274. },
  275. map[revision]struct{}{},
  276. },
  277. {
  278. 7,
  279. &keyIndex{
  280. key: []byte("foo"),
  281. modified: revision{16, 0},
  282. generations: []generation{
  283. {created: revision{8, 0}, ver: 3, revs: []revision{{main: 8}, {main: 10}, {main: 12}}},
  284. {created: revision{14, 0}, ver: 3, revs: []revision{{main: 14}, {main: 14, sub: 1}, {main: 16}}},
  285. {},
  286. },
  287. },
  288. map[revision]struct{}{},
  289. },
  290. {
  291. 8,
  292. &keyIndex{
  293. key: []byte("foo"),
  294. modified: revision{16, 0},
  295. generations: []generation{
  296. {created: revision{8, 0}, ver: 3, revs: []revision{{main: 8}, {main: 10}, {main: 12}}},
  297. {created: revision{14, 0}, ver: 3, revs: []revision{{main: 14}, {main: 14, sub: 1}, {main: 16}}},
  298. {},
  299. },
  300. },
  301. map[revision]struct{}{
  302. {main: 8}: {},
  303. },
  304. },
  305. {
  306. 9,
  307. &keyIndex{
  308. key: []byte("foo"),
  309. modified: revision{16, 0},
  310. generations: []generation{
  311. {created: revision{8, 0}, ver: 3, revs: []revision{{main: 8}, {main: 10}, {main: 12}}},
  312. {created: revision{14, 0}, ver: 3, revs: []revision{{main: 14}, {main: 14, sub: 1}, {main: 16}}},
  313. {},
  314. },
  315. },
  316. map[revision]struct{}{
  317. {main: 8}: {},
  318. },
  319. },
  320. {
  321. 10,
  322. &keyIndex{
  323. key: []byte("foo"),
  324. modified: revision{16, 0},
  325. generations: []generation{
  326. {created: revision{8, 0}, ver: 3, revs: []revision{{main: 10}, {main: 12}}},
  327. {created: revision{14, 0}, ver: 3, revs: []revision{{main: 14}, {main: 14, sub: 1}, {main: 16}}},
  328. {},
  329. },
  330. },
  331. map[revision]struct{}{
  332. {main: 10}: {},
  333. },
  334. },
  335. {
  336. 11,
  337. &keyIndex{
  338. key: []byte("foo"),
  339. modified: revision{16, 0},
  340. generations: []generation{
  341. {created: revision{8, 0}, ver: 3, revs: []revision{{main: 10}, {main: 12}}},
  342. {created: revision{14, 0}, ver: 3, revs: []revision{{main: 14}, {main: 14, sub: 1}, {main: 16}}},
  343. {},
  344. },
  345. },
  346. map[revision]struct{}{
  347. {main: 10}: {},
  348. },
  349. },
  350. {
  351. 12,
  352. &keyIndex{
  353. key: []byte("foo"),
  354. modified: revision{16, 0},
  355. generations: []generation{
  356. {created: revision{14, 0}, ver: 3, revs: []revision{{main: 14}, {main: 14, sub: 1}, {main: 16}}},
  357. {},
  358. },
  359. },
  360. map[revision]struct{}{},
  361. },
  362. {
  363. 13,
  364. &keyIndex{
  365. key: []byte("foo"),
  366. modified: revision{16, 0},
  367. generations: []generation{
  368. {created: revision{14, 0}, ver: 3, revs: []revision{{main: 14}, {main: 14, sub: 1}, {main: 16}}},
  369. {},
  370. },
  371. },
  372. map[revision]struct{}{},
  373. },
  374. {
  375. 14,
  376. &keyIndex{
  377. key: []byte("foo"),
  378. modified: revision{16, 0},
  379. generations: []generation{
  380. {created: revision{14, 0}, ver: 3, revs: []revision{{main: 14, sub: 1}, {main: 16}}},
  381. {},
  382. },
  383. },
  384. map[revision]struct{}{
  385. {main: 14, sub: 1}: {},
  386. },
  387. },
  388. {
  389. 15,
  390. &keyIndex{
  391. key: []byte("foo"),
  392. modified: revision{16, 0},
  393. generations: []generation{
  394. {created: revision{14, 0}, ver: 3, revs: []revision{{main: 14, sub: 1}, {main: 16}}},
  395. {},
  396. },
  397. },
  398. map[revision]struct{}{
  399. {main: 14, sub: 1}: {},
  400. },
  401. },
  402. {
  403. 16,
  404. &keyIndex{
  405. key: []byte("foo"),
  406. modified: revision{16, 0},
  407. generations: []generation{
  408. {},
  409. },
  410. },
  411. map[revision]struct{}{},
  412. },
  413. }
  414. // Continuous Compaction and finding Keep
  415. ki := newTestKeyIndex()
  416. for i, tt := range tests {
  417. am := make(map[revision]struct{})
  418. kiclone := cloneKeyIndex(ki)
  419. ki.keep(tt.compact, am)
  420. if !reflect.DeepEqual(ki, kiclone) {
  421. t.Errorf("#%d: ki = %+v, want %+v", i, ki, kiclone)
  422. }
  423. if !reflect.DeepEqual(am, tt.wam) {
  424. t.Errorf("#%d: am = %+v, want %+v", i, am, tt.wam)
  425. }
  426. am = make(map[revision]struct{})
  427. ki.compact(zap.NewExample(), tt.compact, am)
  428. if !reflect.DeepEqual(ki, tt.wki) {
  429. t.Errorf("#%d: ki = %+v, want %+v", i, ki, tt.wki)
  430. }
  431. if !reflect.DeepEqual(am, tt.wam) {
  432. t.Errorf("#%d: am = %+v, want %+v", i, am, tt.wam)
  433. }
  434. }
  435. // Jump Compaction and finding Keep
  436. ki = newTestKeyIndex()
  437. for i, tt := range tests {
  438. if (i%2 == 0 && i < 6) || (i%2 == 1 && i > 6) {
  439. am := make(map[revision]struct{})
  440. kiclone := cloneKeyIndex(ki)
  441. ki.keep(tt.compact, am)
  442. if !reflect.DeepEqual(ki, kiclone) {
  443. t.Errorf("#%d: ki = %+v, want %+v", i, ki, kiclone)
  444. }
  445. if !reflect.DeepEqual(am, tt.wam) {
  446. t.Errorf("#%d: am = %+v, want %+v", i, am, tt.wam)
  447. }
  448. am = make(map[revision]struct{})
  449. ki.compact(zap.NewExample(), tt.compact, am)
  450. if !reflect.DeepEqual(ki, tt.wki) {
  451. t.Errorf("#%d: ki = %+v, want %+v", i, ki, tt.wki)
  452. }
  453. if !reflect.DeepEqual(am, tt.wam) {
  454. t.Errorf("#%d: am = %+v, want %+v", i, am, tt.wam)
  455. }
  456. }
  457. }
  458. kiClone := newTestKeyIndex()
  459. // Once Compaction and finding Keep
  460. for i, tt := range tests {
  461. ki := newTestKeyIndex()
  462. am := make(map[revision]struct{})
  463. ki.keep(tt.compact, am)
  464. if !reflect.DeepEqual(ki, kiClone) {
  465. t.Errorf("#%d: ki = %+v, want %+v", i, ki, kiClone)
  466. }
  467. if !reflect.DeepEqual(am, tt.wam) {
  468. t.Errorf("#%d: am = %+v, want %+v", i, am, tt.wam)
  469. }
  470. am = make(map[revision]struct{})
  471. ki.compact(zap.NewExample(), tt.compact, am)
  472. if !reflect.DeepEqual(ki, tt.wki) {
  473. t.Errorf("#%d: ki = %+v, want %+v", i, ki, tt.wki)
  474. }
  475. if !reflect.DeepEqual(am, tt.wam) {
  476. t.Errorf("#%d: am = %+v, want %+v", i, am, tt.wam)
  477. }
  478. }
  479. }
  480. func cloneKeyIndex(ki *keyIndex) *keyIndex {
  481. generations := make([]generation, len(ki.generations))
  482. for i, gen := range ki.generations {
  483. generations[i] = *cloneGeneration(&gen)
  484. }
  485. return &keyIndex{ki.key, ki.modified, generations}
  486. }
  487. func cloneGeneration(g *generation) *generation {
  488. if g.revs == nil {
  489. return &generation{g.ver, g.created, nil}
  490. }
  491. tmp := make([]revision, len(g.revs))
  492. copy(tmp, g.revs)
  493. return &generation{g.ver, g.created, tmp}
  494. }
  495. // test that compact on version that higher than last modified version works well
  496. func TestKeyIndexCompactOnFurtherRev(t *testing.T) {
  497. ki := &keyIndex{key: []byte("foo")}
  498. ki.put(zap.NewExample(), 1, 0)
  499. ki.put(zap.NewExample(), 2, 0)
  500. am := make(map[revision]struct{})
  501. ki.compact(zap.NewExample(), 3, am)
  502. wki := &keyIndex{
  503. key: []byte("foo"),
  504. modified: revision{2, 0},
  505. generations: []generation{
  506. {created: revision{1, 0}, ver: 2, revs: []revision{{main: 2}}},
  507. },
  508. }
  509. wam := map[revision]struct{}{
  510. {main: 2}: {},
  511. }
  512. if !reflect.DeepEqual(ki, wki) {
  513. t.Errorf("ki = %+v, want %+v", ki, wki)
  514. }
  515. if !reflect.DeepEqual(am, wam) {
  516. t.Errorf("am = %+v, want %+v", am, wam)
  517. }
  518. }
  519. func TestKeyIndexIsEmpty(t *testing.T) {
  520. tests := []struct {
  521. ki *keyIndex
  522. w bool
  523. }{
  524. {
  525. &keyIndex{
  526. key: []byte("foo"),
  527. generations: []generation{{}},
  528. },
  529. true,
  530. },
  531. {
  532. &keyIndex{
  533. key: []byte("foo"),
  534. modified: revision{2, 0},
  535. generations: []generation{
  536. {created: revision{1, 0}, ver: 2, revs: []revision{{main: 2}}},
  537. },
  538. },
  539. false,
  540. },
  541. }
  542. for i, tt := range tests {
  543. g := tt.ki.isEmpty()
  544. if g != tt.w {
  545. t.Errorf("#%d: isEmpty = %v, want %v", i, g, tt.w)
  546. }
  547. }
  548. }
  549. func TestKeyIndexFindGeneration(t *testing.T) {
  550. ki := newTestKeyIndex()
  551. tests := []struct {
  552. rev int64
  553. wg *generation
  554. }{
  555. {0, nil},
  556. {1, nil},
  557. {2, &ki.generations[0]},
  558. {3, &ki.generations[0]},
  559. {4, &ki.generations[0]},
  560. {5, &ki.generations[0]},
  561. {6, nil},
  562. {7, nil},
  563. {8, &ki.generations[1]},
  564. {9, &ki.generations[1]},
  565. {10, &ki.generations[1]},
  566. {11, &ki.generations[1]},
  567. {12, nil},
  568. {13, nil},
  569. }
  570. for i, tt := range tests {
  571. g := ki.findGeneration(tt.rev)
  572. if g != tt.wg {
  573. t.Errorf("#%d: generation = %+v, want %+v", i, g, tt.wg)
  574. }
  575. }
  576. }
  577. func TestKeyIndexLess(t *testing.T) {
  578. ki := &keyIndex{key: []byte("foo")}
  579. tests := []struct {
  580. ki *keyIndex
  581. w bool
  582. }{
  583. {&keyIndex{key: []byte("doo")}, false},
  584. {&keyIndex{key: []byte("foo")}, false},
  585. {&keyIndex{key: []byte("goo")}, true},
  586. }
  587. for i, tt := range tests {
  588. g := ki.Less(tt.ki)
  589. if g != tt.w {
  590. t.Errorf("#%d: Less = %v, want %v", i, g, tt.w)
  591. }
  592. }
  593. }
  594. func TestGenerationIsEmpty(t *testing.T) {
  595. tests := []struct {
  596. g *generation
  597. w bool
  598. }{
  599. {nil, true},
  600. {&generation{}, true},
  601. {&generation{revs: []revision{{main: 1}}}, false},
  602. }
  603. for i, tt := range tests {
  604. g := tt.g.isEmpty()
  605. if g != tt.w {
  606. t.Errorf("#%d: isEmpty = %v, want %v", i, g, tt.w)
  607. }
  608. }
  609. }
  610. func TestGenerationWalk(t *testing.T) {
  611. g := &generation{
  612. ver: 3,
  613. created: revision{2, 0},
  614. revs: []revision{{main: 2}, {main: 4}, {main: 6}},
  615. }
  616. tests := []struct {
  617. f func(rev revision) bool
  618. wi int
  619. }{
  620. {func(rev revision) bool { return rev.main >= 7 }, 2},
  621. {func(rev revision) bool { return rev.main >= 6 }, 1},
  622. {func(rev revision) bool { return rev.main >= 5 }, 1},
  623. {func(rev revision) bool { return rev.main >= 4 }, 0},
  624. {func(rev revision) bool { return rev.main >= 3 }, 0},
  625. {func(rev revision) bool { return rev.main >= 2 }, -1},
  626. }
  627. for i, tt := range tests {
  628. idx := g.walk(tt.f)
  629. if idx != tt.wi {
  630. t.Errorf("#%d: index = %d, want %d", i, idx, tt.wi)
  631. }
  632. }
  633. }
  634. func newTestKeyIndex() *keyIndex {
  635. // key: "foo"
  636. // rev: 16
  637. // generations:
  638. // {empty}
  639. // {{14, 0}[1], {14, 1}[2], {16, 0}(t)[3]}
  640. // {{8, 0}[1], {10, 0}[2], {12, 0}(t)[3]}
  641. // {{2, 0}[1], {4, 0}[2], {6, 0}(t)[3]}
  642. ki := &keyIndex{key: []byte("foo")}
  643. ki.put(zap.NewExample(), 2, 0)
  644. ki.put(zap.NewExample(), 4, 0)
  645. ki.tombstone(zap.NewExample(), 6, 0)
  646. ki.put(zap.NewExample(), 8, 0)
  647. ki.put(zap.NewExample(), 10, 0)
  648. ki.tombstone(zap.NewExample(), 12, 0)
  649. ki.put(zap.NewExample(), 14, 0)
  650. ki.put(zap.NewExample(), 14, 1)
  651. ki.tombstone(zap.NewExample(), 16, 0)
  652. return ki
  653. }