Merge branch 'master' into columnfamilies

main
Igor Canadi 11 years ago
commit 8b169e949a
  1. 4
      db/memtable.cc
  2. 2
      db/perf_context_test.cc
  3. 37
      db/prefix_test.cc
  4. 2
      util/arena.h
  5. 2
      util/crc32c.cc
  6. 11
      util/hash_linklist_rep.cc
  7. 14
      util/hash_skiplist_rep.cc

@ -562,8 +562,8 @@ size_t MemTable::CountSuccessiveMergeEntries(const LookupKey& key) {
const char* entry = iter->key(); const char* entry = iter->key();
uint32_t key_length = 0; uint32_t key_length = 0;
const char* iter_key_ptr = GetVarint32Ptr(entry, entry + 5, &key_length); const char* iter_key_ptr = GetVarint32Ptr(entry, entry + 5, &key_length);
if (!comparator_.comparator.user_comparator()->Compare( if (comparator_.comparator.user_comparator()->Compare(
Slice(iter_key_ptr, key_length - 8), key.user_key()) == 0) { Slice(iter_key_ptr, key_length - 8), key.user_key()) != 0) {
break; break;
} }

@ -10,6 +10,8 @@
#include "rocksdb/db.h" #include "rocksdb/db.h"
#include "rocksdb/perf_context.h" #include "rocksdb/perf_context.h"
#include "rocksdb/slice_transform.h"
#include "rocksdb/memtablerep.h"
#include "util/histogram.h" #include "util/histogram.h"
#include "util/stop_watch.h" #include "util/stop_watch.h"
#include "util/testharness.h" #include "util/testharness.h"

@ -369,6 +369,43 @@ TEST(PrefixTest, TestResult) {
} }
} }
TEST(PrefixTest, FullIterator) {
while (NextOptions(1000000)) {
DestroyDB(kDbName, Options());
auto db = OpenDb();
WriteOptions write_options;
std::vector<uint64_t> prefixes;
for (uint64_t i = 0; i < 100; ++i) {
prefixes.push_back(i);
}
std::random_shuffle(prefixes.begin(), prefixes.end());
for (auto prefix : prefixes) {
for (uint64_t i = 0; i < 200; ++i) {
TestKey test_key(prefix, i);
Slice key = TestKeyToSlice(test_key);
ASSERT_OK(db->Put(write_options, key, Slice("0")));
}
}
auto func = [](void* db_void) {
auto db = reinterpret_cast<DB*>(db_void);
std::unique_ptr<Iterator> iter(db->NewIterator(ReadOptions()));
iter->SeekToFirst();
for (int i = 0; i < 3; ++i) {
iter->Next();
}
};
auto env = Env::Default();
for (int i = 0; i < 16; ++i) {
env->StartThread(func, reinterpret_cast<void*>(db.get()));
}
env->WaitForJoin();
}
}
TEST(PrefixTest, DynamicPrefixIterator) { TEST(PrefixTest, DynamicPrefixIterator) {
while (NextOptions(FLAGS_bucket_count)) { while (NextOptions(FLAGS_bucket_count)) {
std::cout << "*** Mem table: " << options.memtable_factory->Name() std::cout << "*** Mem table: " << options.memtable_factory->Name()

@ -52,6 +52,8 @@ class Arena {
// same size of that allocation. // same size of that allocation.
virtual size_t IrregularBlockNum() const { return irregular_block_num; } virtual size_t IrregularBlockNum() const { return irregular_block_num; }
size_t BlockSize() const { return kBlockSize; }
private: private:
// Number of bytes allocated in one block // Number of bytes allocated in one block
const size_t kBlockSize; const size_t kBlockSize;

@ -291,9 +291,11 @@ static inline uint32_t LE_LOAD32(const uint8_t *p) {
return DecodeFixed32(reinterpret_cast<const char*>(p)); return DecodeFixed32(reinterpret_cast<const char*>(p));
} }
#ifdef __SSE4_2__
static inline uint64_t LE_LOAD64(const uint8_t *p) { static inline uint64_t LE_LOAD64(const uint8_t *p) {
return DecodeFixed64(reinterpret_cast<const char*>(p)); return DecodeFixed64(reinterpret_cast<const char*>(p));
} }
#endif
static inline void Slow_CRC32(uint64_t* l, uint8_t const **p) { static inline void Slow_CRC32(uint64_t* l, uint8_t const **p) {
uint32_t c = *l ^ LE_LOAD32(*p); uint32_t c = *l ^ LE_LOAD32(*p);

@ -141,8 +141,8 @@ class HashLinkListRep : public MemTableRep {
class FullListIterator : public MemTableRep::Iterator { class FullListIterator : public MemTableRep::Iterator {
public: public:
explicit FullListIterator(FullList* list) explicit FullListIterator(FullList* list, Arena* arena)
: iter_(list), full_list_(list) {} : iter_(list), full_list_(list), arena_(arena) {}
virtual ~FullListIterator() { virtual ~FullListIterator() {
} }
@ -196,6 +196,7 @@ class HashLinkListRep : public MemTableRep {
FullList::Iterator iter_; FullList::Iterator iter_;
// To destruct with the iterator. // To destruct with the iterator.
std::unique_ptr<FullList> full_list_; std::unique_ptr<FullList> full_list_;
std::unique_ptr<Arena> arena_;
std::string tmp_; // For passing to EncodeKey std::string tmp_; // For passing to EncodeKey
}; };
@ -416,7 +417,9 @@ void HashLinkListRep::Get(const LookupKey& k, void* callback_args,
} }
MemTableRep::Iterator* HashLinkListRep::GetIterator() { MemTableRep::Iterator* HashLinkListRep::GetIterator() {
auto list = new FullList(compare_, arena_); // allocate a new arena of similar size to the one currently in use
Arena* new_arena = new Arena(arena_->BlockSize());
auto list = new FullList(compare_, new_arena);
for (size_t i = 0; i < bucket_size_; ++i) { for (size_t i = 0; i < bucket_size_; ++i) {
auto bucket = GetBucket(i); auto bucket = GetBucket(i);
if (bucket != nullptr) { if (bucket != nullptr) {
@ -426,7 +429,7 @@ MemTableRep::Iterator* HashLinkListRep::GetIterator() {
} }
} }
} }
return new FullListIterator(list); return new FullListIterator(list, new_arena);
} }
MemTableRep::Iterator* HashLinkListRep::GetPrefixIterator( MemTableRep::Iterator* HashLinkListRep::GetPrefixIterator(

@ -81,10 +81,9 @@ class HashSkipListRep : public MemTableRep {
class Iterator : public MemTableRep::Iterator { class Iterator : public MemTableRep::Iterator {
public: public:
explicit Iterator(Bucket* list, bool own_list = true) explicit Iterator(Bucket* list, bool own_list = true,
: list_(list), Arena* arena = nullptr)
iter_(list), : list_(list), iter_(list), own_list_(own_list), arena_(arena) {}
own_list_(own_list) {}
virtual ~Iterator() { virtual ~Iterator() {
// if we own the list, we should also delete it // if we own the list, we should also delete it
@ -163,6 +162,7 @@ class HashSkipListRep : public MemTableRep {
// here we track if we own list_. If we own it, we are also // here we track if we own list_. If we own it, we are also
// responsible for it's cleaning. This is a poor man's shared_ptr // responsible for it's cleaning. This is a poor man's shared_ptr
bool own_list_; bool own_list_;
std::unique_ptr<Arena> arena_;
std::string tmp_; // For passing to EncodeKey std::string tmp_; // For passing to EncodeKey
}; };
@ -289,7 +289,9 @@ void HashSkipListRep::Get(const LookupKey& k, void* callback_args,
} }
MemTableRep::Iterator* HashSkipListRep::GetIterator() { MemTableRep::Iterator* HashSkipListRep::GetIterator() {
auto list = new Bucket(compare_, arena_); // allocate a new arena of similar size to the one currently in use
Arena* new_arena = new Arena(arena_->BlockSize());
auto list = new Bucket(compare_, new_arena);
for (size_t i = 0; i < bucket_size_; ++i) { for (size_t i = 0; i < bucket_size_; ++i) {
auto bucket = GetBucket(i); auto bucket = GetBucket(i);
if (bucket != nullptr) { if (bucket != nullptr) {
@ -299,7 +301,7 @@ MemTableRep::Iterator* HashSkipListRep::GetIterator() {
} }
} }
} }
return new Iterator(list); return new Iterator(list, true, new_arena);
} }
MemTableRep::Iterator* HashSkipListRep::GetPrefixIterator(const Slice& prefix) { MemTableRep::Iterator* HashSkipListRep::GetPrefixIterator(const Slice& prefix) {

Loading…
Cancel
Save