1*9507f98cSAndroid Build Coastguard Worker // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
2*9507f98cSAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*9507f98cSAndroid Build Coastguard Worker // found in the LICENSE file. See the AUTHORS file for names of contributors.
4*9507f98cSAndroid Build Coastguard Worker
5*9507f98cSAndroid Build Coastguard Worker #include "db/dbformat.h"
6*9507f98cSAndroid Build Coastguard Worker
7*9507f98cSAndroid Build Coastguard Worker #include "gtest/gtest.h"
8*9507f98cSAndroid Build Coastguard Worker #include "util/logging.h"
9*9507f98cSAndroid Build Coastguard Worker
10*9507f98cSAndroid Build Coastguard Worker namespace leveldb {
11*9507f98cSAndroid Build Coastguard Worker
IKey(const std::string & user_key,uint64_t seq,ValueType vt)12*9507f98cSAndroid Build Coastguard Worker static std::string IKey(const std::string& user_key, uint64_t seq,
13*9507f98cSAndroid Build Coastguard Worker ValueType vt) {
14*9507f98cSAndroid Build Coastguard Worker std::string encoded;
15*9507f98cSAndroid Build Coastguard Worker AppendInternalKey(&encoded, ParsedInternalKey(user_key, seq, vt));
16*9507f98cSAndroid Build Coastguard Worker return encoded;
17*9507f98cSAndroid Build Coastguard Worker }
18*9507f98cSAndroid Build Coastguard Worker
Shorten(const std::string & s,const std::string & l)19*9507f98cSAndroid Build Coastguard Worker static std::string Shorten(const std::string& s, const std::string& l) {
20*9507f98cSAndroid Build Coastguard Worker std::string result = s;
21*9507f98cSAndroid Build Coastguard Worker InternalKeyComparator(BytewiseComparator()).FindShortestSeparator(&result, l);
22*9507f98cSAndroid Build Coastguard Worker return result;
23*9507f98cSAndroid Build Coastguard Worker }
24*9507f98cSAndroid Build Coastguard Worker
ShortSuccessor(const std::string & s)25*9507f98cSAndroid Build Coastguard Worker static std::string ShortSuccessor(const std::string& s) {
26*9507f98cSAndroid Build Coastguard Worker std::string result = s;
27*9507f98cSAndroid Build Coastguard Worker InternalKeyComparator(BytewiseComparator()).FindShortSuccessor(&result);
28*9507f98cSAndroid Build Coastguard Worker return result;
29*9507f98cSAndroid Build Coastguard Worker }
30*9507f98cSAndroid Build Coastguard Worker
TestKey(const std::string & key,uint64_t seq,ValueType vt)31*9507f98cSAndroid Build Coastguard Worker static void TestKey(const std::string& key, uint64_t seq, ValueType vt) {
32*9507f98cSAndroid Build Coastguard Worker std::string encoded = IKey(key, seq, vt);
33*9507f98cSAndroid Build Coastguard Worker
34*9507f98cSAndroid Build Coastguard Worker Slice in(encoded);
35*9507f98cSAndroid Build Coastguard Worker ParsedInternalKey decoded("", 0, kTypeValue);
36*9507f98cSAndroid Build Coastguard Worker
37*9507f98cSAndroid Build Coastguard Worker ASSERT_TRUE(ParseInternalKey(in, &decoded));
38*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(key, decoded.user_key.ToString());
39*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(seq, decoded.sequence);
40*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(vt, decoded.type);
41*9507f98cSAndroid Build Coastguard Worker
42*9507f98cSAndroid Build Coastguard Worker ASSERT_TRUE(!ParseInternalKey(Slice("bar"), &decoded));
43*9507f98cSAndroid Build Coastguard Worker }
44*9507f98cSAndroid Build Coastguard Worker
TEST(FormatTest,InternalKey_EncodeDecode)45*9507f98cSAndroid Build Coastguard Worker TEST(FormatTest, InternalKey_EncodeDecode) {
46*9507f98cSAndroid Build Coastguard Worker const char* keys[] = {"", "k", "hello", "longggggggggggggggggggggg"};
47*9507f98cSAndroid Build Coastguard Worker const uint64_t seq[] = {1,
48*9507f98cSAndroid Build Coastguard Worker 2,
49*9507f98cSAndroid Build Coastguard Worker 3,
50*9507f98cSAndroid Build Coastguard Worker (1ull << 8) - 1,
51*9507f98cSAndroid Build Coastguard Worker 1ull << 8,
52*9507f98cSAndroid Build Coastguard Worker (1ull << 8) + 1,
53*9507f98cSAndroid Build Coastguard Worker (1ull << 16) - 1,
54*9507f98cSAndroid Build Coastguard Worker 1ull << 16,
55*9507f98cSAndroid Build Coastguard Worker (1ull << 16) + 1,
56*9507f98cSAndroid Build Coastguard Worker (1ull << 32) - 1,
57*9507f98cSAndroid Build Coastguard Worker 1ull << 32,
58*9507f98cSAndroid Build Coastguard Worker (1ull << 32) + 1};
59*9507f98cSAndroid Build Coastguard Worker for (int k = 0; k < sizeof(keys) / sizeof(keys[0]); k++) {
60*9507f98cSAndroid Build Coastguard Worker for (int s = 0; s < sizeof(seq) / sizeof(seq[0]); s++) {
61*9507f98cSAndroid Build Coastguard Worker TestKey(keys[k], seq[s], kTypeValue);
62*9507f98cSAndroid Build Coastguard Worker TestKey("hello", 1, kTypeDeletion);
63*9507f98cSAndroid Build Coastguard Worker }
64*9507f98cSAndroid Build Coastguard Worker }
65*9507f98cSAndroid Build Coastguard Worker }
66*9507f98cSAndroid Build Coastguard Worker
TEST(FormatTest,InternalKey_DecodeFromEmpty)67*9507f98cSAndroid Build Coastguard Worker TEST(FormatTest, InternalKey_DecodeFromEmpty) {
68*9507f98cSAndroid Build Coastguard Worker InternalKey internal_key;
69*9507f98cSAndroid Build Coastguard Worker
70*9507f98cSAndroid Build Coastguard Worker ASSERT_TRUE(!internal_key.DecodeFrom(""));
71*9507f98cSAndroid Build Coastguard Worker }
72*9507f98cSAndroid Build Coastguard Worker
TEST(FormatTest,InternalKeyShortSeparator)73*9507f98cSAndroid Build Coastguard Worker TEST(FormatTest, InternalKeyShortSeparator) {
74*9507f98cSAndroid Build Coastguard Worker // When user keys are same
75*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(IKey("foo", 100, kTypeValue),
76*9507f98cSAndroid Build Coastguard Worker Shorten(IKey("foo", 100, kTypeValue), IKey("foo", 99, kTypeValue)));
77*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(
78*9507f98cSAndroid Build Coastguard Worker IKey("foo", 100, kTypeValue),
79*9507f98cSAndroid Build Coastguard Worker Shorten(IKey("foo", 100, kTypeValue), IKey("foo", 101, kTypeValue)));
80*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(
81*9507f98cSAndroid Build Coastguard Worker IKey("foo", 100, kTypeValue),
82*9507f98cSAndroid Build Coastguard Worker Shorten(IKey("foo", 100, kTypeValue), IKey("foo", 100, kTypeValue)));
83*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(
84*9507f98cSAndroid Build Coastguard Worker IKey("foo", 100, kTypeValue),
85*9507f98cSAndroid Build Coastguard Worker Shorten(IKey("foo", 100, kTypeValue), IKey("foo", 100, kTypeDeletion)));
86*9507f98cSAndroid Build Coastguard Worker
87*9507f98cSAndroid Build Coastguard Worker // When user keys are misordered
88*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(IKey("foo", 100, kTypeValue),
89*9507f98cSAndroid Build Coastguard Worker Shorten(IKey("foo", 100, kTypeValue), IKey("bar", 99, kTypeValue)));
90*9507f98cSAndroid Build Coastguard Worker
91*9507f98cSAndroid Build Coastguard Worker // When user keys are different, but correctly ordered
92*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(
93*9507f98cSAndroid Build Coastguard Worker IKey("g", kMaxSequenceNumber, kValueTypeForSeek),
94*9507f98cSAndroid Build Coastguard Worker Shorten(IKey("foo", 100, kTypeValue), IKey("hello", 200, kTypeValue)));
95*9507f98cSAndroid Build Coastguard Worker
96*9507f98cSAndroid Build Coastguard Worker // When start user key is prefix of limit user key
97*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(
98*9507f98cSAndroid Build Coastguard Worker IKey("foo", 100, kTypeValue),
99*9507f98cSAndroid Build Coastguard Worker Shorten(IKey("foo", 100, kTypeValue), IKey("foobar", 200, kTypeValue)));
100*9507f98cSAndroid Build Coastguard Worker
101*9507f98cSAndroid Build Coastguard Worker // When limit user key is prefix of start user key
102*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(
103*9507f98cSAndroid Build Coastguard Worker IKey("foobar", 100, kTypeValue),
104*9507f98cSAndroid Build Coastguard Worker Shorten(IKey("foobar", 100, kTypeValue), IKey("foo", 200, kTypeValue)));
105*9507f98cSAndroid Build Coastguard Worker }
106*9507f98cSAndroid Build Coastguard Worker
TEST(FormatTest,InternalKeyShortestSuccessor)107*9507f98cSAndroid Build Coastguard Worker TEST(FormatTest, InternalKeyShortestSuccessor) {
108*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(IKey("g", kMaxSequenceNumber, kValueTypeForSeek),
109*9507f98cSAndroid Build Coastguard Worker ShortSuccessor(IKey("foo", 100, kTypeValue)));
110*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ(IKey("\xff\xff", 100, kTypeValue),
111*9507f98cSAndroid Build Coastguard Worker ShortSuccessor(IKey("\xff\xff", 100, kTypeValue)));
112*9507f98cSAndroid Build Coastguard Worker }
113*9507f98cSAndroid Build Coastguard Worker
TEST(FormatTest,ParsedInternalKeyDebugString)114*9507f98cSAndroid Build Coastguard Worker TEST(FormatTest, ParsedInternalKeyDebugString) {
115*9507f98cSAndroid Build Coastguard Worker ParsedInternalKey key("The \"key\" in 'single quotes'", 42, kTypeValue);
116*9507f98cSAndroid Build Coastguard Worker
117*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("'The \"key\" in 'single quotes'' @ 42 : 1", key.DebugString());
118*9507f98cSAndroid Build Coastguard Worker }
119*9507f98cSAndroid Build Coastguard Worker
TEST(FormatTest,InternalKeyDebugString)120*9507f98cSAndroid Build Coastguard Worker TEST(FormatTest, InternalKeyDebugString) {
121*9507f98cSAndroid Build Coastguard Worker InternalKey key("The \"key\" in 'single quotes'", 42, kTypeValue);
122*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("'The \"key\" in 'single quotes'' @ 42 : 1", key.DebugString());
123*9507f98cSAndroid Build Coastguard Worker
124*9507f98cSAndroid Build Coastguard Worker InternalKey invalid_key;
125*9507f98cSAndroid Build Coastguard Worker ASSERT_EQ("(bad)", invalid_key.DebugString());
126*9507f98cSAndroid Build Coastguard Worker }
127*9507f98cSAndroid Build Coastguard Worker
128*9507f98cSAndroid Build Coastguard Worker } // namespace leveldb
129*9507f98cSAndroid Build Coastguard Worker
130