1// Copyright (c) 2012, Suryandaru Triandana <syndtr@gmail.com> 2// All rights reserved. 3// 4// Use of this source code is governed by a BSD-style license that can be 5// found in the LICENSE file. 6 7package leveldb 8 9import ( 10 "bytes" 11 "testing" 12 13 "github.com/syndtr/goleveldb/leveldb/comparer" 14) 15 16var defaultIComparer = &iComparer{comparer.DefaultComparer} 17 18func ikey(key string, seq uint64, kt keyType) internalKey { 19 return makeInternalKey(nil, []byte(key), uint64(seq), kt) 20} 21 22func shortSep(a, b []byte) []byte { 23 dst := make([]byte, len(a)) 24 dst = defaultIComparer.Separator(dst[:0], a, b) 25 if dst == nil { 26 return a 27 } 28 return dst 29} 30 31func shortSuccessor(b []byte) []byte { 32 dst := make([]byte, len(b)) 33 dst = defaultIComparer.Successor(dst[:0], b) 34 if dst == nil { 35 return b 36 } 37 return dst 38} 39 40func testSingleKey(t *testing.T, key string, seq uint64, kt keyType) { 41 ik := ikey(key, seq, kt) 42 43 if !bytes.Equal(ik.ukey(), []byte(key)) { 44 t.Errorf("user key does not equal, got %v, want %v", string(ik.ukey()), key) 45 } 46 47 rseq, rt := ik.parseNum() 48 if rseq != seq { 49 t.Errorf("seq number does not equal, got %v, want %v", rseq, seq) 50 } 51 if rt != kt { 52 t.Errorf("type does not equal, got %v, want %v", rt, kt) 53 } 54 55 if rukey, rseq, rt, kerr := parseInternalKey(ik); kerr == nil { 56 if !bytes.Equal(rukey, []byte(key)) { 57 t.Errorf("user key does not equal, got %v, want %v", string(ik.ukey()), key) 58 } 59 if rseq != seq { 60 t.Errorf("seq number does not equal, got %v, want %v", rseq, seq) 61 } 62 if rt != kt { 63 t.Errorf("type does not equal, got %v, want %v", rt, kt) 64 } 65 } else { 66 t.Errorf("key error: %v", kerr) 67 } 68} 69 70func TestInternalKey_EncodeDecode(t *testing.T) { 71 keys := []string{"", "k", "hello", "longggggggggggggggggggggg"} 72 seqs := []uint64{ 73 1, 2, 3, 74 (1 << 8) - 1, 1 << 8, (1 << 8) + 1, 75 (1 << 16) - 1, 1 << 16, (1 << 16) + 1, 76 (1 << 32) - 1, 1 << 32, (1 << 32) + 1, 77 } 78 for _, key := range keys { 79 for _, seq := range seqs { 80 testSingleKey(t, key, seq, keyTypeVal) 81 testSingleKey(t, "hello", 1, keyTypeDel) 82 } 83 } 84} 85 86func assertBytes(t *testing.T, want, got []byte) { 87 if !bytes.Equal(got, want) { 88 t.Errorf("assert failed, got %v, want %v", got, want) 89 } 90} 91 92func TestInternalKeyShortSeparator(t *testing.T) { 93 // When user keys are same 94 assertBytes(t, ikey("foo", 100, keyTypeVal), 95 shortSep(ikey("foo", 100, keyTypeVal), 96 ikey("foo", 99, keyTypeVal))) 97 assertBytes(t, ikey("foo", 100, keyTypeVal), 98 shortSep(ikey("foo", 100, keyTypeVal), 99 ikey("foo", 101, keyTypeVal))) 100 assertBytes(t, ikey("foo", 100, keyTypeVal), 101 shortSep(ikey("foo", 100, keyTypeVal), 102 ikey("foo", 100, keyTypeVal))) 103 assertBytes(t, ikey("foo", 100, keyTypeVal), 104 shortSep(ikey("foo", 100, keyTypeVal), 105 ikey("foo", 100, keyTypeDel))) 106 107 // When user keys are misordered 108 assertBytes(t, ikey("foo", 100, keyTypeVal), 109 shortSep(ikey("foo", 100, keyTypeVal), 110 ikey("bar", 99, keyTypeVal))) 111 112 // When user keys are different, but correctly ordered 113 assertBytes(t, ikey("g", uint64(keyMaxSeq), keyTypeSeek), 114 shortSep(ikey("foo", 100, keyTypeVal), 115 ikey("hello", 200, keyTypeVal))) 116 117 // When start user key is prefix of limit user key 118 assertBytes(t, ikey("foo", 100, keyTypeVal), 119 shortSep(ikey("foo", 100, keyTypeVal), 120 ikey("foobar", 200, keyTypeVal))) 121 122 // When limit user key is prefix of start user key 123 assertBytes(t, ikey("foobar", 100, keyTypeVal), 124 shortSep(ikey("foobar", 100, keyTypeVal), 125 ikey("foo", 200, keyTypeVal))) 126} 127 128func TestInternalKeyShortestSuccessor(t *testing.T) { 129 assertBytes(t, ikey("g", uint64(keyMaxSeq), keyTypeSeek), 130 shortSuccessor(ikey("foo", 100, keyTypeVal))) 131 assertBytes(t, ikey("\xff\xff", 100, keyTypeVal), 132 shortSuccessor(ikey("\xff\xff", 100, keyTypeVal))) 133} 134