30 for (std::string::reverse_iterator rit = str.rbegin();
31 rit != str.rend(); ++rit) {
40 virtual const char*
Name()
const {
41 return "leveldb.ReverseBytewiseComparator";
50 const Slice& limit)
const {
51 std::string s =
Reverse(*start);
70 assert(cmp == &reverse_key_comparator);
71 std::string rev =
Reverse(*key);
84 bool operator()(
const std::string& a,
const std::string& b)
const {
94 const std::string&
contents()
const {
return contents_; }
101 contents_.append(data.
data(), data.
size());
113 : contents_(contents.data(), contents.size()) {
118 uint64_t
Size()
const {
return contents_.size(); }
121 char* scratch)
const {
122 if (offset > contents_.size()) {
125 if (offset + n > contents_.size()) {
126 n = contents_.size() - offset;
128 memcpy(scratch, &contents_[offset], n);
129 *result =
Slice(scratch, n);
137 typedef std::map<std::string, std::string, STLLessThan>
KVMap;
146 void Add(
const std::string& key,
const Slice& value) {
154 std::vector<std::string>* keys,
158 for (KVMap::const_iterator it = data_.begin();
161 keys->push_back(it->first);
164 Status s = FinishImpl(options, *kvmap);
169 virtual Status FinishImpl(
const Options& options,
const KVMap& data) = 0;
171 virtual Iterator* NewIterator()
const = 0;
173 virtual const KVMap&
data() {
return data_; }
175 virtual DB*
db()
const {
return NULL; }
195 for (KVMap::const_iterator it = data.begin();
198 builder.
Add(it->first, it->second);
203 contents.
data = data_;
206 block_ =
new Block(contents);
210 return block_->NewIterator(comparator_);
225 source_(NULL), table_(NULL) {
235 for (KVMap::const_iterator it = data.begin();
238 builder.
Add(it->first, it->second);
258 return table_->ApproximateOffsetOf(key);
280 virtual bool Valid()
const {
return iter_->Valid(); }
285 iter_->Seek(encoded);
289 virtual void Next() { iter_->Next(); }
290 virtual void Prev() { iter_->Prev(); }
297 return Slice(
"corrupted key");
304 return status_.
ok() ? iter_->status() : status_;
320 internal_comparator_(cmp) {
321 memtable_ =
new MemTable(internal_comparator_);
329 memtable_ =
new MemTable(internal_comparator_);
332 for (KVMap::const_iterator it = data.begin();
335 memtable_->Add(seq,
kTypeValue, it->first, it->second);
364 for (KVMap::const_iterator it = data.begin();
368 batch.
Put(it->first, it->second);
377 virtual DB*
db()
const {
return db_; }
391 status =
DB::Open(options, name, &db_);
449 options_.block_size = 256;
473 void Add(
const std::string& key,
const std::string& value) {
474 constructor_->Add(key, value);
478 std::vector<std::string> keys;
480 constructor_->Finish(options_, &keys, &data);
482 TestForwardScan(keys, data);
483 TestBackwardScan(keys, data);
484 TestRandomAccess(rnd, keys, data);
489 Iterator* iter = constructor_->NewIterator();
492 for (KVMap::const_iterator model_iter = data.begin();
493 model_iter != data.end();
495 ASSERT_EQ(ToString(data, model_iter), ToString(iter));
504 Iterator* iter = constructor_->NewIterator();
507 for (KVMap::const_reverse_iterator model_iter = data.rbegin();
508 model_iter != data.rend();
510 ASSERT_EQ(ToString(data, model_iter), ToString(iter));
518 const std::vector<std::string>& keys,
521 Iterator* iter = constructor_->NewIterator();
523 KVMap::const_iterator model_iter = data.begin();
524 if (kVerbose) fprintf(stderr,
"---\n");
525 for (
int i = 0; i < 200; i++) {
526 const int toss = rnd->
Uniform(5);
530 if (kVerbose) fprintf(stderr,
"Next\n");
533 ASSERT_EQ(ToString(data, model_iter), ToString(iter));
539 if (kVerbose) fprintf(stderr,
"SeekToFirst\n");
541 model_iter = data.begin();
542 ASSERT_EQ(ToString(data, model_iter), ToString(iter));
547 std::string key = PickRandomKey(rnd, keys);
548 model_iter = data.lower_bound(key);
549 if (kVerbose) fprintf(stderr,
"Seek '%s'\n",
552 ASSERT_EQ(ToString(data, model_iter), ToString(iter));
558 if (kVerbose) fprintf(stderr,
"Prev\n");
560 if (model_iter == data.begin()) {
561 model_iter = data.end();
565 ASSERT_EQ(ToString(data, model_iter), ToString(iter));
571 if (kVerbose) fprintf(stderr,
"SeekToLast\n");
574 model_iter = data.end();
576 std::string last = data.rbegin()->first;
577 model_iter = data.lower_bound(last);
579 ASSERT_EQ(ToString(data, model_iter), ToString(iter));
587 std::string
ToString(
const KVMap& data,
const KVMap::const_iterator& it) {
588 if (it == data.end()) {
591 return "'" + it->first +
"->" + it->second +
"'";
596 const KVMap::const_reverse_iterator& it) {
597 if (it == data.rend()) {
600 return "'" + it->first +
"->" + it->second +
"'";
616 const int index = rnd->
Uniform(keys.size());
617 std::string result = keys[index];
624 if (result.size() > 0 && result[result.size()-1] >
'\0') {
625 result[result.size()-1]--;
640 DB*
db()
const {
return constructor_->db(); }
650 Init(kTestArgList[i]);
660 char data[
sizeof(uint32_t)];
661 memset(data, 0,
sizeof(data));
663 contents.
data =
Slice(data,
sizeof(data));
666 Block block(contents);
680 Init(kTestArgList[i]);
689 Init(kTestArgList[i]);
698 Init(kTestArgList[i]);
709 Init(kTestArgList[i]);
711 Add(
"\xff\xff",
"v3");
718 Init(kTestArgList[i]);
720 for (
int num_entries = 0; num_entries < 2000;
721 num_entries += (num_entries < 50 ? 1 : 200)) {
722 if ((num_entries % 10) == 0) {
723 fprintf(stderr,
"case %d of %d: num_entries = %d\n",
724 (i + 1),
int(kNumTestArgs), num_entries);
726 for (
int e = 0; e < num_entries; e++) {
740 int num_entries = 100000;
741 for (
int e = 0; e < num_entries; e++) {
753 snprintf(name,
sizeof(name),
"leveldb.num-files-at-level%d", level);
755 files += atoi(value.c_str());
768 batch.
Put(std::string(
"k1"), std::string(
"v1"));
769 batch.
Put(std::string(
"k2"), std::string(
"v2"));
770 batch.
Put(std::string(
"k3"), std::string(
"v3"));
771 batch.
Put(std::string(
"largekey"), std::string(
"vlarge"));
776 while (iter->
Valid()) {
777 fprintf(stderr,
"key: '%s' -> '%s'\n",
787 static bool Between(uint64_t val, uint64_t low, uint64_t high) {
788 bool result = (val >= low) && (val <= high);
790 fprintf(stderr,
"Value %llu is not in range [%llu, %llu]\n",
791 (
unsigned long long)(val),
792 (
unsigned long long)(low),
793 (
unsigned long long)(high));
802 c.
Add(
"k01",
"hello");
803 c.
Add(
"k02",
"hello2");
804 c.
Add(
"k03", std::string(10000,
'x'));
805 c.
Add(
"k04", std::string(200000,
'x'));
806 c.
Add(
"k05", std::string(300000,
'x'));
807 c.
Add(
"k06",
"hello3");
808 c.
Add(
"k07", std::string(100000,
'x'));
809 std::vector<std::string> keys;
814 c.
Finish(options, &keys, &kvmap);
832 Slice in =
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
833 return port::Snappy_Compress(in.
data(), in.
size(), &out);
838 fprintf(stderr,
"skipping compression tests\n");
845 c.
Add(
"k01",
"hello");
847 c.
Add(
"k03",
"hello3");
849 std::vector<std::string> keys;
854 c.
Finish(options, &keys, &kvmap);
857 static const int kSlop = 1000;
858 const int expected = 2500;
859 const int min_z = expected - kSlop;
860 const int max_z = expected + kSlop;
874 int main(
int argc,
char** argv) {
virtual const char * Name() const
virtual void Seek(const Slice &target)
static const SequenceNumber kMaxSequenceNumber
std::string PickRandomKey(Random *rnd, const std::vector< std::string > &keys)
StringSource(const Slice &contents)
STLLessThan(const Comparator *c)
virtual Status FinishImpl(const Options &options, const KVMap &data)
virtual Iterator * NewIterator() const
static const int kNumLevels
virtual Status FinishImpl(const Options &options, const KVMap &data)
static void Increment(const Comparator *cmp, std::string *key)
virtual Slice key() const =0
static ReverseKeyComparator reverse_key_comparator
virtual void SeekToLast()
virtual Slice value() const =0
std::string ToString(const KVMap &data, const KVMap::const_iterator &it)
void Add(const std::string &key, const std::string &value)
virtual ~KeyConvertingIterator()
BlockConstructor(const Comparator *cmp)
Constructor * constructor_
void TestRandomAccess(Random *rnd, const std::vector< std::string > &keys, const KVMap &data)
virtual Status Append(const Slice &data)
static bool Between(uint64_t val, uint64_t low, uint64_t high)
virtual void FindShortestSeparator(std::string *start, const Slice &limit) const =0
void Init(const TestArgs &args)
static void SetSequence(WriteBatch *batch, SequenceNumber seq)
static Status Open(const Options &options, RandomAccessFile *file, uint64_t file_size, Table **table)
static Status InsertInto(const WriteBatch *batch, MemTable *memtable)
virtual void SeekToFirst()=0
std::map< std::string, std::string, STLLessThan > KVMap
virtual Iterator * NewIterator() const
void Add(const std::string &key, const Slice &value)
virtual Iterator * NewIterator() const
void TestBackwardScan(const std::vector< std::string > &keys, const KVMap &data)
int main(int argc, char **argv)
std::string ToString() const
virtual void Seek(const Slice &target)=0
Iterator * NewIterator(const Comparator *comparator)
static std::string Reverse(const Slice &key)
static const TestArgs kTestArgList[]
static const int kNumTestArgs
virtual void SeekToLast()=0
virtual void FindShortSuccessor(std::string *key) const
bool ParseInternalKey(const Slice &internal_key, ParsedInternalKey *result)
void AppendInternalKey(std::string *result, const ParsedInternalKey &key)
Slice CompressibleString(Random *rnd, double compressed_fraction, size_t len, std::string *dst)
Status DestroyDB(const std::string &dbname, const Options &options)
MemTableConstructor(const Comparator *cmp)
static Status Corruption(const Slice &msg, const Slice &msg2=Slice())
virtual bool Valid() const
std::string ToString() const
virtual Status status() const
virtual Iterator * NewIterator() const
static Status Open(const Options &options, const std::string &name, DB **dbptr)
uint64_t FileSize() const
std::string ToString(const Iterator *it)
virtual Status FinishImpl(const Options &options, const KVMap &data)
std::string EscapeString(const Slice &value)
TEST(AutoCompactTest, ReadAll)
Constructor(const Comparator *cmp)
const Comparator * comparator_
virtual void FindShortSuccessor(std::string *key) const =0
uint32_t Skewed(int max_log)
virtual Status Read(uint64_t offset, size_t n, Slice *result, char *scratch) const
InternalKeyComparator internal_comparator_
virtual void FindShortestSeparator(std::string *start, const Slice &limit) const
DBConstructor(const Comparator *cmp)
bool operator()(const std::string &a, const std::string &b) const
void Finish(const Options &options, std::vector< std::string > *keys, KVMap *kvmap)
virtual const KVMap & data()
const Comparator * BytewiseComparator()
const Comparator * comparator
static Status InvalidArgument(const Slice &msg, const Slice &msg2=Slice())
uint64_t ApproximateOffsetOf(const Slice &key) const
virtual Slice value() const
const Comparator * comparator_
virtual int Compare(const Slice &a, const Slice &b) const =0
static bool SnappyCompressionSupported()
TableConstructor(const Comparator *cmp)
void Add(const Slice &key, const Slice &value)
std::string RandomKey(Random *rnd, int len)
Slice RandomString(Random *rnd, int len, std::string *dst)
virtual Status FinishImpl(const Options &options, const KVMap &data)
const char * data() const
void TestForwardScan(const std::vector< std::string > &keys, const KVMap &data)
const std::string & contents() const
virtual void SeekToFirst()
std::string ToString(const KVMap &data, const KVMap::const_reverse_iterator &it)
virtual bool Valid() const =0
virtual Slice key() const
void Put(const Slice &key, const Slice &value)
KeyConvertingIterator(Iterator *iter)
virtual int Compare(const Slice &a, const Slice &b) const
void Add(const Slice &key, const Slice &value)
static const int kVerbose
CompressionType compression