1179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// Use of this source code is governed by a BSD-style license that can be 3179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// found in the LICENSE file. See the AUTHORS file for names of contributors. 4179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 5fbd97aa4c5325eace57d24b89845b9581bac9324jorlow@chromium.org#include "leveldb/db.h" 699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com#include "leveldb/filter_policy.h" 7179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include "db/db_impl.h" 8179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include "db/filename.h" 9179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include "db/version_set.h" 10179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include "db/write_batch_internal.h" 1199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com#include "leveldb/cache.h" 12fbd97aa4c5325eace57d24b89845b9581bac9324jorlow@chromium.org#include "leveldb/env.h" 13fbd97aa4c5325eace57d24b89845b9581bac9324jorlow@chromium.org#include "leveldb/table.h" 1499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com#include "util/hash.h" 15179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include "util/logging.h" 16394a4b425a6a8aca3244fc26ec77c101a11a632cgabor@google.com#include "util/mutexlock.h" 17179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include "util/testharness.h" 18179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include "util/testutil.h" 19179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 20179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgnamespace leveldb { 21179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 22179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgstatic std::string RandomString(Random* rnd, int len) { 23179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org std::string r; 24179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org test::RandomString(rnd, len, &r); 25179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return r; 26179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 27179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 2899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.comnamespace { 2999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.comclass AtomicCounter { 3099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com private: 3199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com port::Mutex mu_; 3299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com int count_; 3399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com public: 3499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com AtomicCounter() : count_(0) { } 3599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com void Increment() { 3611042098fe3e5a16ad70c388bb5914a907ae3faedgrogan@chromium.org IncrementBy(1); 3711042098fe3e5a16ad70c388bb5914a907ae3faedgrogan@chromium.org } 3811042098fe3e5a16ad70c388bb5914a907ae3faedgrogan@chromium.org void IncrementBy(int count) { 3999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com MutexLock l(&mu_); 4011042098fe3e5a16ad70c388bb5914a907ae3faedgrogan@chromium.org count_ += count; 4199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } 4299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com int Read() { 4399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com MutexLock l(&mu_); 4499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com return count_; 4599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } 4699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com void Reset() { 4799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com MutexLock l(&mu_); 4899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com count_ = 0; 4999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } 5099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com}; 5111042098fe3e5a16ad70c388bb5914a907ae3faedgrogan@chromium.org 5211042098fe3e5a16ad70c388bb5914a907ae3faedgrogan@chromium.orgvoid DelayMilliseconds(int millis) { 5311042098fe3e5a16ad70c388bb5914a907ae3faedgrogan@chromium.org Env::Default()->SleepForMicroseconds(millis * 1000); 5411042098fe3e5a16ad70c388bb5914a907ae3faedgrogan@chromium.org} 5599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com} 5699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com 578cd4ab8303620197cf24282ae8639060efbb326egabor@google.com// Special Env used to delay background operations 588cd4ab8303620197cf24282ae8639060efbb326egabor@google.comclass SpecialEnv : public EnvWrapper { 598cd4ab8303620197cf24282ae8639060efbb326egabor@google.com public: 604935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org // sstable/log Sync() calls are blocked while this pointer is non-NULL. 614935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org port::AtomicPointer delay_data_sync_; 624935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org 634935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org // sstable/log Sync() calls return an error. 644935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org port::AtomicPointer data_sync_error_; 658cd4ab8303620197cf24282ae8639060efbb326egabor@google.com 66e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com // Simulate no-space errors while this pointer is non-NULL. 67e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com port::AtomicPointer no_space_; 68e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com 69158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com // Simulate non-writable file system while this pointer is non-NULL 70158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com port::AtomicPointer non_writable_; 71158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com 7285e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org // Force sync of manifest files to fail while this pointer is non-NULL 7385e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org port::AtomicPointer manifest_sync_error_; 7485e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org 7585e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org // Force write to manifest files to fail while this pointer is non-NULL 7685e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org port::AtomicPointer manifest_write_error_; 7785e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org 7899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com bool count_random_reads_; 7999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com AtomicCounter random_read_counter_; 8099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com 818cd4ab8303620197cf24282ae8639060efbb326egabor@google.com explicit SpecialEnv(Env* base) : EnvWrapper(base) { 824935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org delay_data_sync_.Release_Store(NULL); 834935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org data_sync_error_.Release_Store(NULL); 84e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com no_space_.Release_Store(NULL); 85158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com non_writable_.Release_Store(NULL); 8699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com count_random_reads_ = false; 8785e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org manifest_sync_error_.Release_Store(NULL); 8885e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org manifest_write_error_.Release_Store(NULL); 898cd4ab8303620197cf24282ae8639060efbb326egabor@google.com } 908cd4ab8303620197cf24282ae8639060efbb326egabor@google.com 918cd4ab8303620197cf24282ae8639060efbb326egabor@google.com Status NewWritableFile(const std::string& f, WritableFile** r) { 924935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org class DataFile : public WritableFile { 938cd4ab8303620197cf24282ae8639060efbb326egabor@google.com private: 948cd4ab8303620197cf24282ae8639060efbb326egabor@google.com SpecialEnv* env_; 958cd4ab8303620197cf24282ae8639060efbb326egabor@google.com WritableFile* base_; 968cd4ab8303620197cf24282ae8639060efbb326egabor@google.com 978cd4ab8303620197cf24282ae8639060efbb326egabor@google.com public: 984935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org DataFile(SpecialEnv* env, WritableFile* base) 998cd4ab8303620197cf24282ae8639060efbb326egabor@google.com : env_(env), 1008cd4ab8303620197cf24282ae8639060efbb326egabor@google.com base_(base) { 1018cd4ab8303620197cf24282ae8639060efbb326egabor@google.com } 1024935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org ~DataFile() { delete base_; } 103e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com Status Append(const Slice& data) { 104e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com if (env_->no_space_.Acquire_Load() != NULL) { 105e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com // Drop writes on the floor 106e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com return Status::OK(); 107e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com } else { 108e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com return base_->Append(data); 109e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com } 110e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com } 1118cd4ab8303620197cf24282ae8639060efbb326egabor@google.com Status Close() { return base_->Close(); } 1128cd4ab8303620197cf24282ae8639060efbb326egabor@google.com Status Flush() { return base_->Flush(); } 1138cd4ab8303620197cf24282ae8639060efbb326egabor@google.com Status Sync() { 1144935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org if (env_->data_sync_error_.Acquire_Load() != NULL) { 1154935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org return Status::IOError("simulated data sync error"); 1164935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org } 1174935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org while (env_->delay_data_sync_.Acquire_Load() != NULL) { 11811042098fe3e5a16ad70c388bb5914a907ae3faedgrogan@chromium.org DelayMilliseconds(100); 1198cd4ab8303620197cf24282ae8639060efbb326egabor@google.com } 1208cd4ab8303620197cf24282ae8639060efbb326egabor@google.com return base_->Sync(); 1218cd4ab8303620197cf24282ae8639060efbb326egabor@google.com } 1228cd4ab8303620197cf24282ae8639060efbb326egabor@google.com }; 12385e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org class ManifestFile : public WritableFile { 12485e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org private: 12585e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org SpecialEnv* env_; 12685e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org WritableFile* base_; 12785e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org public: 12885e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org ManifestFile(SpecialEnv* env, WritableFile* b) : env_(env), base_(b) { } 12985e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org ~ManifestFile() { delete base_; } 13085e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org Status Append(const Slice& data) { 13185e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org if (env_->manifest_write_error_.Acquire_Load() != NULL) { 13285e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org return Status::IOError("simulated writer error"); 13385e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org } else { 13485e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org return base_->Append(data); 13585e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org } 13685e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org } 13785e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org Status Close() { return base_->Close(); } 13885e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org Status Flush() { return base_->Flush(); } 13985e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org Status Sync() { 14085e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org if (env_->manifest_sync_error_.Acquire_Load() != NULL) { 14185e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org return Status::IOError("simulated sync error"); 14285e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org } else { 14385e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org return base_->Sync(); 14485e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org } 14585e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org } 14685e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org }; 1478cd4ab8303620197cf24282ae8639060efbb326egabor@google.com 148158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com if (non_writable_.Acquire_Load() != NULL) { 149158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com return Status::IOError("simulated write error"); 150158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com } 151158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com 1528cd4ab8303620197cf24282ae8639060efbb326egabor@google.com Status s = target()->NewWritableFile(f, r); 1538cd4ab8303620197cf24282ae8639060efbb326egabor@google.com if (s.ok()) { 1544935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org if (strstr(f.c_str(), ".ldb") != NULL || 1554935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org strstr(f.c_str(), ".log") != NULL) { 1564935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org *r = new DataFile(this, *r); 15785e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org } else if (strstr(f.c_str(), "MANIFEST") != NULL) { 15885e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org *r = new ManifestFile(this, *r); 1598cd4ab8303620197cf24282ae8639060efbb326egabor@google.com } 1608cd4ab8303620197cf24282ae8639060efbb326egabor@google.com } 1618cd4ab8303620197cf24282ae8639060efbb326egabor@google.com return s; 1628cd4ab8303620197cf24282ae8639060efbb326egabor@google.com } 16399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com 16499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Status NewRandomAccessFile(const std::string& f, RandomAccessFile** r) { 16599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com class CountingFile : public RandomAccessFile { 16699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com private: 16799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com RandomAccessFile* target_; 16899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com AtomicCounter* counter_; 16999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com public: 17099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com CountingFile(RandomAccessFile* target, AtomicCounter* counter) 17199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com : target_(target), counter_(counter) { 17299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } 17399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com virtual ~CountingFile() { delete target_; } 17499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com virtual Status Read(uint64_t offset, size_t n, Slice* result, 17599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com char* scratch) const { 17699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com counter_->Increment(); 17799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com return target_->Read(offset, n, result, scratch); 17899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } 17999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com }; 18099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com 18199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Status s = target()->NewRandomAccessFile(f, r); 18299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com if (s.ok() && count_random_reads_) { 18399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com *r = new CountingFile(*r, &random_read_counter_); 18499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } 18599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com return s; 18699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } 1878cd4ab8303620197cf24282ae8639060efbb326egabor@google.com}; 1888cd4ab8303620197cf24282ae8639060efbb326egabor@google.com 189179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgclass DBTest { 19099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com private: 19199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com const FilterPolicy* filter_policy_; 19299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com 19399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // Sequence of option configurations to try 19499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com enum OptionConfig { 19599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com kDefault, 19699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com kFilter, 197158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com kUncompressed, 19899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com kEnd 19999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com }; 20099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com int option_config_; 20199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com 202179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org public: 203179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org std::string dbname_; 2048cd4ab8303620197cf24282ae8639060efbb326egabor@google.com SpecialEnv* env_; 205179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org DB* db_; 206179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 207179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Options last_options_; 208179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 20999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com DBTest() : option_config_(kDefault), 21099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com env_(new SpecialEnv(Env::Default())) { 21199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com filter_policy_ = NewBloomFilterPolicy(10); 212179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org dbname_ = test::TmpDir() + "/db_test"; 213179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org DestroyDB(dbname_, Options()); 214179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org db_ = NULL; 215179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Reopen(); 216179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 217179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 218179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ~DBTest() { 219179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org delete db_; 220179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org DestroyDB(dbname_, Options()); 2218cd4ab8303620197cf24282ae8639060efbb326egabor@google.com delete env_; 22299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com delete filter_policy_; 22399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } 22499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com 22599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // Switch to a fresh database with the next option configuration to 22699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // test. Return false if there are no more configurations to test. 22799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com bool ChangeOptions() { 228158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com option_config_++; 229158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com if (option_config_ >= kEnd) { 23099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com return false; 23199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } else { 23299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com DestroyAndReopen(); 23399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com return true; 23499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } 23599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } 23699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com 23799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // Return the current option configuration. 23899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Options CurrentOptions() { 23999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Options options; 24099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com switch (option_config_) { 24199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com case kFilter: 24299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com options.filter_policy = filter_policy_; 24399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com break; 244158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com case kUncompressed: 245158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com options.compression = kNoCompression; 246158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com break; 24799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com default: 24899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com break; 24999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } 25099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com return options; 251179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 252179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 253179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org DBImpl* dbfull() { 254179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return reinterpret_cast<DBImpl*>(db_); 255179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 256179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 257179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org void Reopen(Options* options = NULL) { 258179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_OK(TryReopen(options)); 259179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 260179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 26199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com void Close() { 26299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com delete db_; 26399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com db_ = NULL; 26499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } 26599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com 266179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org void DestroyAndReopen(Options* options = NULL) { 267179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org delete db_; 268179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org db_ = NULL; 269179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org DestroyDB(dbname_, Options()); 270179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_OK(TryReopen(options)); 271179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 272179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 273179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Status TryReopen(Options* options) { 274179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org delete db_; 275179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org db_ = NULL; 276179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Options opts; 277179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (options != NULL) { 278179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org opts = *options; 279179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } else { 28099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com opts = CurrentOptions(); 281179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org opts.create_if_missing = true; 282179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 283179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org last_options_ = opts; 284179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 285179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return DB::Open(opts, dbname_, &db_); 286179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 287179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 288179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Status Put(const std::string& k, const std::string& v) { 28995e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org return db_->Put(WriteOptions(), k, v); 290179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 291179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 292179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Status Delete(const std::string& k) { 29395e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org return db_->Delete(WriteOptions(), k); 294179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 295179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 296179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org std::string Get(const std::string& k, const Snapshot* snapshot = NULL) { 297179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ReadOptions options; 298179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org options.snapshot = snapshot; 299179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org std::string result; 300179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Status s = db_->Get(options, k, &result); 301179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (s.IsNotFound()) { 302179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org result = "NOT_FOUND"; 303179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } else if (!s.ok()) { 304179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org result = s.ToString(); 305179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 306179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return result; 307179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 308179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 30945b9940be332834440bd5299419f396e38085ebehans@chromium.org // Return a string that contains all key,value pairs in order, 31045b9940be332834440bd5299419f396e38085ebehans@chromium.org // formatted like "(k1->v1)(k2->v2)". 31145b9940be332834440bd5299419f396e38085ebehans@chromium.org std::string Contents() { 31245b9940be332834440bd5299419f396e38085ebehans@chromium.org std::vector<std::string> forward; 31345b9940be332834440bd5299419f396e38085ebehans@chromium.org std::string result; 31445b9940be332834440bd5299419f396e38085ebehans@chromium.org Iterator* iter = db_->NewIterator(ReadOptions()); 31545b9940be332834440bd5299419f396e38085ebehans@chromium.org for (iter->SeekToFirst(); iter->Valid(); iter->Next()) { 31645b9940be332834440bd5299419f396e38085ebehans@chromium.org std::string s = IterStatus(iter); 31745b9940be332834440bd5299419f396e38085ebehans@chromium.org result.push_back('('); 31845b9940be332834440bd5299419f396e38085ebehans@chromium.org result.append(s); 31945b9940be332834440bd5299419f396e38085ebehans@chromium.org result.push_back(')'); 32045b9940be332834440bd5299419f396e38085ebehans@chromium.org forward.push_back(s); 32145b9940be332834440bd5299419f396e38085ebehans@chromium.org } 32245b9940be332834440bd5299419f396e38085ebehans@chromium.org 32345b9940be332834440bd5299419f396e38085ebehans@chromium.org // Check reverse iteration results are the reverse of forward results 3244935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org size_t matched = 0; 32545b9940be332834440bd5299419f396e38085ebehans@chromium.org for (iter->SeekToLast(); iter->Valid(); iter->Prev()) { 32645b9940be332834440bd5299419f396e38085ebehans@chromium.org ASSERT_LT(matched, forward.size()); 32745b9940be332834440bd5299419f396e38085ebehans@chromium.org ASSERT_EQ(IterStatus(iter), forward[forward.size() - matched - 1]); 32845b9940be332834440bd5299419f396e38085ebehans@chromium.org matched++; 32945b9940be332834440bd5299419f396e38085ebehans@chromium.org } 33045b9940be332834440bd5299419f396e38085ebehans@chromium.org ASSERT_EQ(matched, forward.size()); 33145b9940be332834440bd5299419f396e38085ebehans@chromium.org 33245b9940be332834440bd5299419f396e38085ebehans@chromium.org delete iter; 33345b9940be332834440bd5299419f396e38085ebehans@chromium.org return result; 33445b9940be332834440bd5299419f396e38085ebehans@chromium.org } 33545b9940be332834440bd5299419f396e38085ebehans@chromium.org 336179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org std::string AllEntriesFor(const Slice& user_key) { 337179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Iterator* iter = dbfull()->TEST_NewInternalIterator(); 338179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org InternalKey target(user_key, kMaxSequenceNumber, kTypeValue); 339179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org iter->Seek(target.Encode()); 340179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org std::string result; 341179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (!iter->status().ok()) { 342179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org result = iter->status().ToString(); 343179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } else { 344179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org result = "[ "; 345179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org bool first = true; 346179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org while (iter->Valid()) { 347179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ParsedInternalKey ikey; 348179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (!ParseInternalKey(iter->key(), &ikey)) { 349179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org result += "CORRUPTED"; 350179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } else { 35199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com if (last_options_.comparator->Compare(ikey.user_key, user_key) != 0) { 352179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org break; 353179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 354179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (!first) { 355179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org result += ", "; 356179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 357179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org first = false; 358179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org switch (ikey.type) { 359179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org case kTypeValue: 360179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org result += iter->value().ToString(); 361179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org break; 362179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org case kTypeDeletion: 363179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org result += "DEL"; 364179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org break; 365179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 366179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 367179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org iter->Next(); 368179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 369179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (!first) { 370179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org result += " "; 371179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 372179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org result += "]"; 373179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 374179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org delete iter; 375179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return result; 376179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 377179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 378179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org int NumTableFilesAtLevel(int level) { 37995e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org std::string property; 380179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_TRUE( 381179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org db_->GetProperty("leveldb.num-files-at-level" + NumberToString(level), 38295e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org &property)); 38395e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org return atoi(property.c_str()); 384179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 385179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 3868cd4ab8303620197cf24282ae8639060efbb326egabor@google.com int TotalTableFiles() { 3878cd4ab8303620197cf24282ae8639060efbb326egabor@google.com int result = 0; 3888cd4ab8303620197cf24282ae8639060efbb326egabor@google.com for (int level = 0; level < config::kNumLevels; level++) { 3898cd4ab8303620197cf24282ae8639060efbb326egabor@google.com result += NumTableFilesAtLevel(level); 3908cd4ab8303620197cf24282ae8639060efbb326egabor@google.com } 3918cd4ab8303620197cf24282ae8639060efbb326egabor@google.com return result; 3928cd4ab8303620197cf24282ae8639060efbb326egabor@google.com } 3938cd4ab8303620197cf24282ae8639060efbb326egabor@google.com 3945fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com // Return spread of files per level 3955fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com std::string FilesPerLevel() { 3965fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com std::string result; 3975fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com int last_non_zero_offset = 0; 3985fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com for (int level = 0; level < config::kNumLevels; level++) { 3995fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com int f = NumTableFilesAtLevel(level); 4005fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com char buf[100]; 4015fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com snprintf(buf, sizeof(buf), "%s%d", (level ? "," : ""), f); 4025fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com result += buf; 4035fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com if (f > 0) { 4045fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com last_non_zero_offset = result.size(); 4055fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com } 4065fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com } 4075fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com result.resize(last_non_zero_offset); 4085fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com return result; 4095fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com } 4105fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com 411e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com int CountFiles() { 412e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com std::vector<std::string> files; 413e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com env_->GetChildren(dbname_, &files); 414e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com return static_cast<int>(files.size()); 415e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com } 416e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com 417179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org uint64_t Size(const Slice& start, const Slice& limit) { 418179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Range r(start, limit); 419179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org uint64_t size; 420179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org db_->GetApproximateSizes(&r, 1, &size); 421179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return size; 422179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 423179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 424b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org void Compact(const Slice& start, const Slice& limit) { 4255fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com db_->CompactRange(&start, &limit); 4265fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com } 4275fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com 4285fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com // Do n memtable compactions, each of which produces an sstable 4295fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com // covering the range [small,large]. 4305fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com void MakeTables(int n, const std::string& small, const std::string& large) { 4315fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com for (int i = 0; i < n; i++) { 4325fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com Put(small, "begin"); 4335fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com Put(large, "end"); 4345fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com dbfull()->TEST_CompactMemTable(); 435b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org } 436b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org } 437b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org 4388cd4ab8303620197cf24282ae8639060efbb326egabor@google.com // Prevent pushing of new sstables into deeper levels by adding 4398cd4ab8303620197cf24282ae8639060efbb326egabor@google.com // tables that cover a specified range to all levels. 4408cd4ab8303620197cf24282ae8639060efbb326egabor@google.com void FillLevels(const std::string& smallest, const std::string& largest) { 4415fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com MakeTables(config::kNumLevels, smallest, largest); 4428cd4ab8303620197cf24282ae8639060efbb326egabor@google.com } 4438cd4ab8303620197cf24282ae8639060efbb326egabor@google.com 444b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org void DumpFileCounts(const char* label) { 445b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org fprintf(stderr, "---\n%s:\n", label); 446b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org fprintf(stderr, "maxoverlap: %lld\n", 447b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org static_cast<long long>( 448b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org dbfull()->TEST_MaxNextLevelOverlappingBytes())); 449b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org for (int level = 0; level < config::kNumLevels; level++) { 450b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org int num = NumTableFilesAtLevel(level); 451b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org if (num > 0) { 452b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org fprintf(stderr, " level %3d : %d files\n", level, num); 453b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org } 454b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org } 455b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org } 456225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org 4575fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com std::string DumpSSTableList() { 4585fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com std::string property; 4595fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com db_->GetProperty("leveldb.sstables", &property); 4605fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com return property; 4615fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com } 4625fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com 463225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org std::string IterStatus(Iterator* iter) { 464225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org std::string result; 465225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org if (iter->Valid()) { 466225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org result = iter->key().ToString() + "->" + iter->value().ToString(); 467225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org } else { 468225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org result = "(invalid)"; 469225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org } 470225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org return result; 471225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org } 472bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org 473bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org bool DeleteAnSSTFile() { 474bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org std::vector<std::string> filenames; 475bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org ASSERT_OK(env_->GetChildren(dbname_, &filenames)); 476bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org uint64_t number; 477bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org FileType type; 478bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org for (size_t i = 0; i < filenames.size(); i++) { 479bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org if (ParseFileName(filenames[i], &number, &type) && type == kTableFile) { 480bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org ASSERT_OK(env_->DeleteFile(TableFileName(dbname_, number))); 481bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org return true; 482bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org } 483bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org } 484bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org return false; 485bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org } 4862d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.org 4872d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.org // Returns number of files renamed. 4882d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.org int RenameLDBToSST() { 4892d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.org std::vector<std::string> filenames; 4902d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.org ASSERT_OK(env_->GetChildren(dbname_, &filenames)); 4912d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.org uint64_t number; 4922d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.org FileType type; 4932d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.org int files_renamed = 0; 4942d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.org for (size_t i = 0; i < filenames.size(); i++) { 4952d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.org if (ParseFileName(filenames[i], &number, &type) && type == kTableFile) { 4962d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.org const std::string from = TableFileName(dbname_, number); 4972d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.org const std::string to = SSTTableFileName(dbname_, number); 4982d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.org ASSERT_OK(env_->RenameFile(from, to)); 4992d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.org files_renamed++; 5002d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.org } 5012d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.org } 5022d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.org return files_renamed; 5032d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.org } 504179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}; 505179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 506179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgTEST(DBTest, Empty) { 50799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com do { 50899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_TRUE(db_ != NULL); 50999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("NOT_FOUND", Get("foo")); 51099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } while (ChangeOptions()); 511179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 512179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 513179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgTEST(DBTest, ReadWrite) { 51499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com do { 51599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put("foo", "v1")); 51699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("v1", Get("foo")); 51799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put("bar", "v2")); 51899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put("foo", "v3")); 51999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("v3", Get("foo")); 52099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("v2", Get("bar")); 52199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } while (ChangeOptions()); 522179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 523179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 524179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgTEST(DBTest, PutDeleteGet) { 52599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com do { 52699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(db_->Put(WriteOptions(), "foo", "v1")); 52799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("v1", Get("foo")); 52899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(db_->Put(WriteOptions(), "foo", "v2")); 52999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("v2", Get("foo")); 53099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(db_->Delete(WriteOptions(), "foo")); 53199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("NOT_FOUND", Get("foo")); 53299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } while (ChangeOptions()); 533179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 534179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 5358cd4ab8303620197cf24282ae8639060efbb326egabor@google.comTEST(DBTest, GetFromImmutableLayer) { 53699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com do { 53799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Options options = CurrentOptions(); 53899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com options.env = env_; 53999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com options.write_buffer_size = 100000; // Small write buffer 54099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Reopen(&options); 5418cd4ab8303620197cf24282ae8639060efbb326egabor@google.com 54299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put("foo", "v1")); 54399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("v1", Get("foo")); 5448cd4ab8303620197cf24282ae8639060efbb326egabor@google.com 5454935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org env_->delay_data_sync_.Release_Store(env_); // Block sync calls 54699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Put("k1", std::string(100000, 'x')); // Fill memtable 54799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Put("k2", std::string(100000, 'y')); // Trigger compaction 54899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("v1", Get("foo")); 5494935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org env_->delay_data_sync_.Release_Store(NULL); // Release sync calls 55099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } while (ChangeOptions()); 5518cd4ab8303620197cf24282ae8639060efbb326egabor@google.com} 5528cd4ab8303620197cf24282ae8639060efbb326egabor@google.com 5538cd4ab8303620197cf24282ae8639060efbb326egabor@google.comTEST(DBTest, GetFromVersions) { 55499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com do { 55599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put("foo", "v1")); 55699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com dbfull()->TEST_CompactMemTable(); 55799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("v1", Get("foo")); 55899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } while (ChangeOptions()); 5598cd4ab8303620197cf24282ae8639060efbb326egabor@google.com} 5608cd4ab8303620197cf24282ae8639060efbb326egabor@google.com 5618cd4ab8303620197cf24282ae8639060efbb326egabor@google.comTEST(DBTest, GetSnapshot) { 56299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com do { 56399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // Try with both a short key and a long key 56499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com for (int i = 0; i < 2; i++) { 56599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com std::string key = (i == 0) ? std::string("foo") : std::string(200, 'x'); 56699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put(key, "v1")); 56799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com const Snapshot* s1 = db_->GetSnapshot(); 56899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put(key, "v2")); 56999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("v2", Get(key)); 57099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("v1", Get(key, s1)); 57199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com dbfull()->TEST_CompactMemTable(); 57299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("v2", Get(key)); 57399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("v1", Get(key, s1)); 57499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com db_->ReleaseSnapshot(s1); 57599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } 57699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } while (ChangeOptions()); 5778cd4ab8303620197cf24282ae8639060efbb326egabor@google.com} 5788cd4ab8303620197cf24282ae8639060efbb326egabor@google.com 5798cd4ab8303620197cf24282ae8639060efbb326egabor@google.comTEST(DBTest, GetLevel0Ordering) { 58099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com do { 58199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // Check that we process level-0 files in correct order. The code 58299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // below generates two level-0 files where the earlier one comes 58399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // before the later one in the level-0 file list since the earlier 58499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // one has a smaller "smallest" key. 58599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put("bar", "b")); 58699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put("foo", "v1")); 58799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com dbfull()->TEST_CompactMemTable(); 58899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put("foo", "v2")); 58999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com dbfull()->TEST_CompactMemTable(); 59099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("v2", Get("foo")); 59199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } while (ChangeOptions()); 5928cd4ab8303620197cf24282ae8639060efbb326egabor@google.com} 5938cd4ab8303620197cf24282ae8639060efbb326egabor@google.com 5948cd4ab8303620197cf24282ae8639060efbb326egabor@google.comTEST(DBTest, GetOrderedByLevels) { 59599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com do { 59699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put("foo", "v1")); 59799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Compact("a", "z"); 59899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("v1", Get("foo")); 59999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put("foo", "v2")); 60099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("v2", Get("foo")); 60199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com dbfull()->TEST_CompactMemTable(); 60299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("v2", Get("foo")); 60399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } while (ChangeOptions()); 6048cd4ab8303620197cf24282ae8639060efbb326egabor@google.com} 6058cd4ab8303620197cf24282ae8639060efbb326egabor@google.com 6068cd4ab8303620197cf24282ae8639060efbb326egabor@google.comTEST(DBTest, GetPicksCorrectFile) { 60799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com do { 60899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // Arrange to have multiple files in a non-level-0 level. 60999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put("a", "va")); 61099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Compact("a", "b"); 61199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put("x", "vx")); 61299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Compact("x", "y"); 61399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put("f", "vf")); 61499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Compact("f", "g"); 61599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("va", Get("a")); 61699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("vf", Get("f")); 61799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("vx", Get("x")); 61899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } while (ChangeOptions()); 6198cd4ab8303620197cf24282ae8639060efbb326egabor@google.com} 6208cd4ab8303620197cf24282ae8639060efbb326egabor@google.com 621394a4b425a6a8aca3244fc26ec77c101a11a632cgabor@google.comTEST(DBTest, GetEncountersEmptyLevel) { 62299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com do { 62399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // Arrange for the following to happen: 62499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // * sstable A in level 0 62599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // * nothing in level 1 62699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // * sstable B in level 2 62799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // Then do enough Get() calls to arrange for an automatic compaction 62899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // of sstable A. A bug would cause the compaction to be marked as 62999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // occuring at level 1 (instead of the correct level 0). 63099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com 63199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // Step 1: First place sstables in levels 0 and 2 63299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com int compaction_count = 0; 63399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com while (NumTableFilesAtLevel(0) == 0 || 63499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com NumTableFilesAtLevel(2) == 0) { 63599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_LE(compaction_count, 100) << "could not fill levels 0 and 2"; 63699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com compaction_count++; 63799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Put("a", "begin"); 63899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Put("z", "end"); 63999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com dbfull()->TEST_CompactMemTable(); 64099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } 641394a4b425a6a8aca3244fc26ec77c101a11a632cgabor@google.com 64299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // Step 2: clear level 1 if necessary. 64399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com dbfull()->TEST_CompactRange(1, NULL, NULL); 64499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ(NumTableFilesAtLevel(0), 1); 64599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ(NumTableFilesAtLevel(1), 0); 64699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ(NumTableFilesAtLevel(2), 1); 64799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com 648158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com // Step 3: read a bunch of times 649158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com for (int i = 0; i < 1000; i++) { 65099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("NOT_FOUND", Get("missing")); 65199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } 652158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com 653158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com // Step 4: Wait for compaction to finish 65411042098fe3e5a16ad70c388bb5914a907ae3faedgrogan@chromium.org DelayMilliseconds(1000); 655158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com 656158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com ASSERT_EQ(NumTableFilesAtLevel(0), 0); 65799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } while (ChangeOptions()); 658394a4b425a6a8aca3244fc26ec77c101a11a632cgabor@google.com} 659394a4b425a6a8aca3244fc26ec77c101a11a632cgabor@google.com 660225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.orgTEST(DBTest, IterEmpty) { 661225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org Iterator* iter = db_->NewIterator(ReadOptions()); 662225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org 663225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->SeekToFirst(); 664225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "(invalid)"); 665225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org 666225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->SeekToLast(); 667225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "(invalid)"); 668225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org 669225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Seek("foo"); 670225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "(invalid)"); 671225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org 672225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org delete iter; 673225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org} 674225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org 675225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.orgTEST(DBTest, IterSingle) { 676225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_OK(Put("a", "va")); 677225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org Iterator* iter = db_->NewIterator(ReadOptions()); 678225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org 679225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->SeekToFirst(); 680225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "a->va"); 681225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Next(); 682225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "(invalid)"); 683225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->SeekToFirst(); 684225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "a->va"); 685225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Prev(); 686225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "(invalid)"); 687225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org 688225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->SeekToLast(); 689225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "a->va"); 690225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Next(); 691225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "(invalid)"); 692225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->SeekToLast(); 693225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "a->va"); 694225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Prev(); 695225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "(invalid)"); 696225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org 697225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Seek(""); 698225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "a->va"); 699225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Next(); 700225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "(invalid)"); 701225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org 702225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Seek("a"); 703225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "a->va"); 704225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Next(); 705225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "(invalid)"); 706225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org 707225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Seek("b"); 708225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "(invalid)"); 709225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org 710225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org delete iter; 711225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org} 712225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org 713225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.orgTEST(DBTest, IterMulti) { 714225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_OK(Put("a", "va")); 715225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_OK(Put("b", "vb")); 716225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_OK(Put("c", "vc")); 717225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org Iterator* iter = db_->NewIterator(ReadOptions()); 718225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org 719225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->SeekToFirst(); 720225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "a->va"); 721225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Next(); 722225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "b->vb"); 723225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Next(); 724225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "c->vc"); 725225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Next(); 726225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "(invalid)"); 727225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->SeekToFirst(); 728225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "a->va"); 729225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Prev(); 730225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "(invalid)"); 731225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org 732225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->SeekToLast(); 733225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "c->vc"); 734225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Prev(); 735225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "b->vb"); 736225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Prev(); 737225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "a->va"); 738225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Prev(); 739225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "(invalid)"); 740225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->SeekToLast(); 741225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "c->vc"); 742225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Next(); 743225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "(invalid)"); 744225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org 745225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Seek(""); 746225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "a->va"); 747225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Seek("a"); 748225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "a->va"); 749225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Seek("ax"); 750225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "b->vb"); 751225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Seek("b"); 752225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "b->vb"); 753225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Seek("z"); 754225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "(invalid)"); 755225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org 756225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org // Switch from reverse to forward 757225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->SeekToLast(); 758225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Prev(); 759225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Prev(); 760225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Next(); 761225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "b->vb"); 762225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org 763225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org // Switch from forward to reverse 764225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->SeekToFirst(); 765225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Next(); 766225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Next(); 767225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Prev(); 768225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "b->vb"); 769225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org 770225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org // Make sure iter stays at snapshot 771225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_OK(Put("a", "va2")); 772225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_OK(Put("a2", "va3")); 773225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_OK(Put("b", "vb2")); 774225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_OK(Put("c", "vc2")); 775225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_OK(Delete("b")); 776225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->SeekToFirst(); 777225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "a->va"); 778225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Next(); 779225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "b->vb"); 780225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Next(); 781225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "c->vc"); 782225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Next(); 783225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "(invalid)"); 784225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->SeekToLast(); 785225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "c->vc"); 786225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Prev(); 787225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "b->vb"); 788225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Prev(); 789225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "a->va"); 790225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Prev(); 791225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "(invalid)"); 792225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org 793225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org delete iter; 794225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org} 795225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org 796225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.orgTEST(DBTest, IterSmallAndLargeMix) { 797225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_OK(Put("a", "va")); 798225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_OK(Put("b", std::string(100000, 'b'))); 799225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_OK(Put("c", "vc")); 800225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_OK(Put("d", std::string(100000, 'd'))); 801225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_OK(Put("e", std::string(100000, 'e'))); 802225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org 803225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org Iterator* iter = db_->NewIterator(ReadOptions()); 804225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org 805225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->SeekToFirst(); 806225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "a->va"); 807225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Next(); 808225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "b->" + std::string(100000, 'b')); 809225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Next(); 810225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "c->vc"); 811225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Next(); 812225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "d->" + std::string(100000, 'd')); 813225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Next(); 814225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "e->" + std::string(100000, 'e')); 815225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Next(); 816225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "(invalid)"); 817225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org 818225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->SeekToLast(); 819225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "e->" + std::string(100000, 'e')); 820225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Prev(); 821225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "d->" + std::string(100000, 'd')); 822225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Prev(); 823225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "c->vc"); 824225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Prev(); 825225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "b->" + std::string(100000, 'b')); 826225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Prev(); 827225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "a->va"); 828225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org iter->Prev(); 829225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org ASSERT_EQ(IterStatus(iter), "(invalid)"); 830225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org 831225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org delete iter; 832225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org} 833225a272621a5517a1a8dec8956457a121786d7c4jorlow@chromium.org 8347e50a01f8a2820ed7a50c673b5affe0131560ff5gabor@google.comTEST(DBTest, IterMultiWithDelete) { 83599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com do { 83699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put("a", "va")); 83799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put("b", "vb")); 83899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put("c", "vc")); 83999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Delete("b")); 84099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("NOT_FOUND", Get("b")); 8417e50a01f8a2820ed7a50c673b5affe0131560ff5gabor@google.com 84299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Iterator* iter = db_->NewIterator(ReadOptions()); 84399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com iter->Seek("c"); 84499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ(IterStatus(iter), "c->vc"); 84599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com iter->Prev(); 84699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ(IterStatus(iter), "a->va"); 84799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com delete iter; 84899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } while (ChangeOptions()); 8497e50a01f8a2820ed7a50c673b5affe0131560ff5gabor@google.com} 8507e50a01f8a2820ed7a50c673b5affe0131560ff5gabor@google.com 851179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgTEST(DBTest, Recover) { 85299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com do { 85399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put("foo", "v1")); 85499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put("baz", "v5")); 855179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 85699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Reopen(); 85799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("v1", Get("foo")); 858179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 85999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("v1", Get("foo")); 86099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("v5", Get("baz")); 86199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put("bar", "v2")); 86299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put("foo", "v3")); 863179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 86499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Reopen(); 86599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("v3", Get("foo")); 86699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put("foo", "v4")); 86799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("v4", Get("foo")); 86899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("v2", Get("bar")); 86999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("v5", Get("baz")); 87099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } while (ChangeOptions()); 871179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 872179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 873179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgTEST(DBTest, RecoveryWithEmptyLog) { 87499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com do { 87599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put("foo", "v1")); 87699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put("foo", "v2")); 87799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Reopen(); 87899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Reopen(); 87999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put("foo", "v3")); 88099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Reopen(); 88199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("v3", Get("foo")); 88299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } while (ChangeOptions()); 883179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 884179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 8858cd4ab8303620197cf24282ae8639060efbb326egabor@google.com// Check that writes done during a memtable compaction are recovered 8868cd4ab8303620197cf24282ae8639060efbb326egabor@google.com// if the database is shutdown during the memtable compaction. 8878cd4ab8303620197cf24282ae8639060efbb326egabor@google.comTEST(DBTest, RecoverDuringMemtableCompaction) { 88899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com do { 88999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Options options = CurrentOptions(); 89099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com options.env = env_; 89199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com options.write_buffer_size = 1000000; 89299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Reopen(&options); 8938cd4ab8303620197cf24282ae8639060efbb326egabor@google.com 89499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // Trigger a long memtable compaction and reopen the database during it 89599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put("foo", "v1")); // Goes to 1st log file 89699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put("big1", std::string(10000000, 'x'))); // Fills memtable 89799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put("big2", std::string(1000, 'y'))); // Triggers compaction 89899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put("bar", "v2")); // Goes to new log file 8998cd4ab8303620197cf24282ae8639060efbb326egabor@google.com 90099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Reopen(&options); 90199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("v1", Get("foo")); 90299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("v2", Get("bar")); 90399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ(std::string(10000000, 'x'), Get("big1")); 90499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ(std::string(1000, 'y'), Get("big2")); 90599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } while (ChangeOptions()); 9068cd4ab8303620197cf24282ae8639060efbb326egabor@google.com} 9078cd4ab8303620197cf24282ae8639060efbb326egabor@google.com 908179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgstatic std::string Key(int i) { 909179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org char buf[100]; 910179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org snprintf(buf, sizeof(buf), "key%06d", i); 911179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return std::string(buf); 912179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 913179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 914179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgTEST(DBTest, MinorCompactionsHappen) { 91599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Options options = CurrentOptions(); 916179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org options.write_buffer_size = 10000; 917179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Reopen(&options); 918179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 91995e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org const int N = 500; 920179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 9218cd4ab8303620197cf24282ae8639060efbb326egabor@google.com int starting_num_tables = TotalTableFiles(); 922179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org for (int i = 0; i < N; i++) { 923179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_OK(Put(Key(i), Key(i) + std::string(1000, 'v'))); 924179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 9258cd4ab8303620197cf24282ae8639060efbb326egabor@google.com int ending_num_tables = TotalTableFiles(); 926179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_GT(ending_num_tables, starting_num_tables); 927179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 928179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org for (int i = 0; i < N; i++) { 929179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_EQ(Key(i) + std::string(1000, 'v'), Get(Key(i))); 930179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 931179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 932179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Reopen(); 933179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 934179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org for (int i = 0; i < N; i++) { 935179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_EQ(Key(i) + std::string(1000, 'v'), Get(Key(i))); 936179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 937179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 938179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 939179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgTEST(DBTest, RecoverWithLargeLog) { 940179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org { 94199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Options options = CurrentOptions(); 942179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Reopen(&options); 943179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_OK(Put("big1", std::string(200000, '1'))); 944179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_OK(Put("big2", std::string(200000, '2'))); 945179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_OK(Put("small3", std::string(10, '3'))); 946179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_OK(Put("small4", std::string(10, '4'))); 947179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_EQ(NumTableFilesAtLevel(0), 0); 948179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 949179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 950179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // Make sure that if we re-open with a small write buffer size that 951179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // we flush table files in the middle of a large log file. 95299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Options options = CurrentOptions(); 953179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org options.write_buffer_size = 100000; 954179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Reopen(&options); 955179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_EQ(NumTableFilesAtLevel(0), 3); 956179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_EQ(std::string(200000, '1'), Get("big1")); 957179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_EQ(std::string(200000, '2'), Get("big2")); 958179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_EQ(std::string(10, '3'), Get("small3")); 959179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_EQ(std::string(10, '4'), Get("small4")); 960179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_GT(NumTableFilesAtLevel(0), 1); 961179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 962179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 963179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgTEST(DBTest, CompactionsGenerateMultipleFiles) { 96499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Options options = CurrentOptions(); 965179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org options.write_buffer_size = 100000000; // Large write buffer 966179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Reopen(&options); 967179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 968179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Random rnd(301); 969179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 970179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // Write 8MB (80 values, each 100K) 971179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_EQ(NumTableFilesAtLevel(0), 0); 972179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org std::vector<std::string> values; 973179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org for (int i = 0; i < 80; i++) { 974179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org values.push_back(RandomString(&rnd, 100000)); 975179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_OK(Put(Key(i), values[i])); 976179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 977179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 978179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // Reopening moves updates to level-0 979179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Reopen(&options); 9805fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com dbfull()->TEST_CompactRange(0, NULL, NULL); 981179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 982179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_EQ(NumTableFilesAtLevel(0), 0); 983179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_GT(NumTableFilesAtLevel(1), 1); 984179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org for (int i = 0; i < 80; i++) { 985179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_EQ(Get(Key(i)), values[i]); 986179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 987179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 988179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 989917b88dd720b6e658c1fd7812bc61c605f315124gabor@google.comTEST(DBTest, RepeatedWritesToSameKey) { 99099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Options options = CurrentOptions(); 991917b88dd720b6e658c1fd7812bc61c605f315124gabor@google.com options.env = env_; 992917b88dd720b6e658c1fd7812bc61c605f315124gabor@google.com options.write_buffer_size = 100000; // Small write buffer 993917b88dd720b6e658c1fd7812bc61c605f315124gabor@google.com Reopen(&options); 994917b88dd720b6e658c1fd7812bc61c605f315124gabor@google.com 995917b88dd720b6e658c1fd7812bc61c605f315124gabor@google.com // We must have at most one file per level except for level-0, 996917b88dd720b6e658c1fd7812bc61c605f315124gabor@google.com // which may have up to kL0_StopWritesTrigger files. 997917b88dd720b6e658c1fd7812bc61c605f315124gabor@google.com const int kMaxFiles = config::kNumLevels + config::kL0_StopWritesTrigger; 998917b88dd720b6e658c1fd7812bc61c605f315124gabor@google.com 999917b88dd720b6e658c1fd7812bc61c605f315124gabor@google.com Random rnd(301); 1000917b88dd720b6e658c1fd7812bc61c605f315124gabor@google.com std::string value = RandomString(&rnd, 2 * options.write_buffer_size); 1001917b88dd720b6e658c1fd7812bc61c605f315124gabor@google.com for (int i = 0; i < 5 * kMaxFiles; i++) { 1002917b88dd720b6e658c1fd7812bc61c605f315124gabor@google.com Put("key", value); 1003917b88dd720b6e658c1fd7812bc61c605f315124gabor@google.com ASSERT_LE(TotalTableFiles(), kMaxFiles); 1004917b88dd720b6e658c1fd7812bc61c605f315124gabor@google.com fprintf(stderr, "after %d: %d files\n", int(i+1), TotalTableFiles()); 1005917b88dd720b6e658c1fd7812bc61c605f315124gabor@google.com } 1006917b88dd720b6e658c1fd7812bc61c605f315124gabor@google.com} 1007917b88dd720b6e658c1fd7812bc61c605f315124gabor@google.com 1008b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.orgTEST(DBTest, SparseMerge) { 100999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Options options = CurrentOptions(); 1010b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org options.compression = kNoCompression; 1011b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org Reopen(&options); 1012b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org 10138cd4ab8303620197cf24282ae8639060efbb326egabor@google.com FillLevels("A", "Z"); 10148cd4ab8303620197cf24282ae8639060efbb326egabor@google.com 1015b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org // Suppose there is: 1016b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org // small amount of data with prefix A 1017b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org // large amount of data with prefix B 1018b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org // small amount of data with prefix C 1019b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org // and that recent updates have made small changes to all three prefixes. 1020b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org // Check that we do not do a compaction that merges all of B in one shot. 1021b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org const std::string value(1000, 'x'); 1022b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org Put("A", "va"); 1023b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org // Write approximately 100MB of "B" values 1024b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org for (int i = 0; i < 100000; i++) { 1025b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org char key[100]; 1026b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org snprintf(key, sizeof(key), "B%010d", i); 1027b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org Put(key, value); 1028b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org } 1029b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org Put("C", "vc"); 10308cd4ab8303620197cf24282ae8639060efbb326egabor@google.com dbfull()->TEST_CompactMemTable(); 10315fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com dbfull()->TEST_CompactRange(0, NULL, NULL); 1032b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org 1033b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org // Make sparse update 1034b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org Put("A", "va2"); 1035b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org Put("B100", "bvalue2"); 1036b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org Put("C", "vc2"); 1037b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org dbfull()->TEST_CompactMemTable(); 1038b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org 1039b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org // Compactions should not cause us to create a situation where 1040b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org // a file overlaps too much data at the next level. 1041b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org ASSERT_LE(dbfull()->TEST_MaxNextLevelOverlappingBytes(), 20*1048576); 10425fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com dbfull()->TEST_CompactRange(0, NULL, NULL); 1043b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org ASSERT_LE(dbfull()->TEST_MaxNextLevelOverlappingBytes(), 20*1048576); 10445fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com dbfull()->TEST_CompactRange(1, NULL, NULL); 1045b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org ASSERT_LE(dbfull()->TEST_MaxNextLevelOverlappingBytes(), 20*1048576); 1046b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org} 1047b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org 1048179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgstatic bool Between(uint64_t val, uint64_t low, uint64_t high) { 1049179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org bool result = (val >= low) && (val <= high); 1050179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (!result) { 1051179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org fprintf(stderr, "Value %llu is not in range [%llu, %llu]\n", 1052179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org (unsigned long long)(val), 1053179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org (unsigned long long)(low), 1054179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org (unsigned long long)(high)); 1055179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 1056179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return result; 1057179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 1058179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 1059179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgTEST(DBTest, ApproximateSizes) { 106099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com do { 106199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Options options = CurrentOptions(); 106299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com options.write_buffer_size = 100000000; // Large write buffer 106399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com options.compression = kNoCompression; 106499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com DestroyAndReopen(); 1065179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 106699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_TRUE(Between(Size("", "xyz"), 0, 0)); 106799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Reopen(&options); 106899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_TRUE(Between(Size("", "xyz"), 0, 0)); 1069179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 107099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // Write 8MB (80 values, each 100K) 107199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ(NumTableFilesAtLevel(0), 0); 107299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com const int N = 80; 107399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com static const int S1 = 100000; 107499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com static const int S2 = 105000; // Allow some expansion from metadata 107599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Random rnd(301); 107699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com for (int i = 0; i < N; i++) { 107799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put(Key(i), RandomString(&rnd, S1))); 107899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } 1079179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 108099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // 0 because GetApproximateSizes() does not account for memtable space 108199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_TRUE(Between(Size("", Key(50)), 0, 0)); 10828540066c2705c6d2a0595d468a6ab041e4fc72fadgrogan@chromium.org 108399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // Check sizes across recovery by reopening a few times 108499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com for (int run = 0; run < 3; run++) { 108599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Reopen(&options); 10861511be6edb54b6ade2bfad94256f76bc191e92ecdgrogan@chromium.org 108799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com for (int compact_start = 0; compact_start < N; compact_start += 10) { 108899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com for (int i = 0; i < N; i += 10) { 108999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_TRUE(Between(Size("", Key(i)), S1*i, S2*i)); 109099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_TRUE(Between(Size("", Key(i)+".suffix"), S1*(i+1), S2*(i+1))); 109199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_TRUE(Between(Size(Key(i), Key(i+10)), S1*10, S2*10)); 109299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } 109399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_TRUE(Between(Size("", Key(50)), S1*50, S2*50)); 109499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_TRUE(Between(Size("", Key(50)+".suffix"), S1*50, S2*50)); 109599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com 109699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com std::string cstart_str = Key(compact_start); 109799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com std::string cend_str = Key(compact_start + 9); 109899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Slice cstart = cstart_str; 109999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Slice cend = cend_str; 110099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com dbfull()->TEST_CompactRange(0, &cstart, &cend); 1101179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 11021511be6edb54b6ade2bfad94256f76bc191e92ecdgrogan@chromium.org 110399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ(NumTableFilesAtLevel(0), 0); 110499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_GT(NumTableFilesAtLevel(1), 0); 110599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } 110699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } while (ChangeOptions()); 1107179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 1108179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 1109179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgTEST(DBTest, ApproximateSizes_MixOfSmallAndLarge) { 111099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com do { 111199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Options options = CurrentOptions(); 111299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com options.compression = kNoCompression; 111399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Reopen(); 1114179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 111599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Random rnd(301); 111699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com std::string big1 = RandomString(&rnd, 100000); 111799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put(Key(0), RandomString(&rnd, 10000))); 111899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put(Key(1), RandomString(&rnd, 10000))); 111999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put(Key(2), big1)); 112099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put(Key(3), RandomString(&rnd, 10000))); 112199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put(Key(4), big1)); 112299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put(Key(5), RandomString(&rnd, 10000))); 112399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put(Key(6), RandomString(&rnd, 300000))); 112499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put(Key(7), RandomString(&rnd, 10000))); 112599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com 112699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // Check sizes across recovery by reopening a few times 112799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com for (int run = 0; run < 3; run++) { 112899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Reopen(&options); 112999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com 113099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_TRUE(Between(Size("", Key(0)), 0, 0)); 113199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_TRUE(Between(Size("", Key(1)), 10000, 11000)); 113299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_TRUE(Between(Size("", Key(2)), 20000, 21000)); 113399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_TRUE(Between(Size("", Key(3)), 120000, 121000)); 113499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_TRUE(Between(Size("", Key(4)), 130000, 131000)); 113599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_TRUE(Between(Size("", Key(5)), 230000, 231000)); 113699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_TRUE(Between(Size("", Key(6)), 240000, 241000)); 113799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_TRUE(Between(Size("", Key(7)), 540000, 541000)); 113899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_TRUE(Between(Size("", Key(8)), 550000, 560000)); 113999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com 114099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_TRUE(Between(Size(Key(3), Key(5)), 110000, 111000)); 114199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com 114299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com dbfull()->TEST_CompactRange(0, NULL, NULL); 114399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } 114499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } while (ChangeOptions()); 1145179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 1146179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 1147179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgTEST(DBTest, IteratorPinsRef) { 1148179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Put("foo", "hello"); 1149179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 1150179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // Get iterator that will yield the current contents of the DB. 1151179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Iterator* iter = db_->NewIterator(ReadOptions()); 1152179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 1153179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // Write to force compactions 1154179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Put("foo", "newvalue1"); 1155179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org for (int i = 0; i < 100; i++) { 1156179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_OK(Put(Key(i), Key(i) + std::string(100000, 'v'))); // 100K values 1157179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 1158179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Put("foo", "newvalue2"); 1159179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 1160179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org iter->SeekToFirst(); 1161179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_TRUE(iter->Valid()); 1162179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_EQ("foo", iter->key().ToString()); 1163179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_EQ("hello", iter->value().ToString()); 1164179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org iter->Next(); 1165179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_TRUE(!iter->Valid()); 1166179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org delete iter; 1167179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 1168179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 1169179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgTEST(DBTest, Snapshot) { 117099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com do { 117199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Put("foo", "v1"); 117299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com const Snapshot* s1 = db_->GetSnapshot(); 117399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Put("foo", "v2"); 117499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com const Snapshot* s2 = db_->GetSnapshot(); 117599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Put("foo", "v3"); 117699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com const Snapshot* s3 = db_->GetSnapshot(); 117799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com 117899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Put("foo", "v4"); 117999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("v1", Get("foo", s1)); 118099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("v2", Get("foo", s2)); 118199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("v3", Get("foo", s3)); 118299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("v4", Get("foo")); 118399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com 118499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com db_->ReleaseSnapshot(s3); 118599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("v1", Get("foo", s1)); 118699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("v2", Get("foo", s2)); 118799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("v4", Get("foo")); 1188179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 118999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com db_->ReleaseSnapshot(s1); 119099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("v2", Get("foo", s2)); 119199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("v4", Get("foo")); 11928cd4ab8303620197cf24282ae8639060efbb326egabor@google.com 119399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com db_->ReleaseSnapshot(s2); 119499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("v4", Get("foo")); 119599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } while (ChangeOptions()); 119699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com} 1197179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 119899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.comTEST(DBTest, HiddenValuesAreRemoved) { 119999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com do { 120099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Random rnd(301); 120199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com FillLevels("a", "z"); 120299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com 120399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com std::string big = RandomString(&rnd, 50000); 120499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Put("foo", big); 120599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Put("pastfoo", "v"); 120699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com const Snapshot* snapshot = db_->GetSnapshot(); 120799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Put("foo", "tiny"); 120899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Put("pastfoo2", "v2"); // Advance sequence number one more 120999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com 121099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(dbfull()->TEST_CompactMemTable()); 121199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_GT(NumTableFilesAtLevel(0), 0); 121299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com 121399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ(big, Get("foo", snapshot)); 121499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_TRUE(Between(Size("", "pastfoo"), 50000, 60000)); 121599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com db_->ReleaseSnapshot(snapshot); 121699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ(AllEntriesFor("foo"), "[ tiny, " + big + " ]"); 121799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Slice x("x"); 121899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com dbfull()->TEST_CompactRange(0, NULL, &x); 121999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ(AllEntriesFor("foo"), "[ tiny ]"); 122099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ(NumTableFilesAtLevel(0), 0); 122199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_GE(NumTableFilesAtLevel(1), 1); 122299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com dbfull()->TEST_CompactRange(1, NULL, &x); 122399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ(AllEntriesFor("foo"), "[ tiny ]"); 1224179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 122599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_TRUE(Between(Size("", "pastfoo"), 0, 1000)); 122699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } while (ChangeOptions()); 1227179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 1228179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 1229179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgTEST(DBTest, DeletionMarkers1) { 1230179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Put("foo", "v1"); 1231179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_OK(dbfull()->TEST_CompactMemTable()); 1232917b88dd720b6e658c1fd7812bc61c605f315124gabor@google.com const int last = config::kMaxMemCompactLevel; 12338cd4ab8303620197cf24282ae8639060efbb326egabor@google.com ASSERT_EQ(NumTableFilesAtLevel(last), 1); // foo => v1 is now in last level 12348cd4ab8303620197cf24282ae8639060efbb326egabor@google.com 12358cd4ab8303620197cf24282ae8639060efbb326egabor@google.com // Place a table at level last-1 to prevent merging with preceding mutation 12368cd4ab8303620197cf24282ae8639060efbb326egabor@google.com Put("a", "begin"); 12378cd4ab8303620197cf24282ae8639060efbb326egabor@google.com Put("z", "end"); 12388cd4ab8303620197cf24282ae8639060efbb326egabor@google.com dbfull()->TEST_CompactMemTable(); 12398cd4ab8303620197cf24282ae8639060efbb326egabor@google.com ASSERT_EQ(NumTableFilesAtLevel(last), 1); 12408cd4ab8303620197cf24282ae8639060efbb326egabor@google.com ASSERT_EQ(NumTableFilesAtLevel(last-1), 1); 12418cd4ab8303620197cf24282ae8639060efbb326egabor@google.com 1242179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Delete("foo"); 1243179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Put("foo", "v2"); 1244179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_EQ(AllEntriesFor("foo"), "[ v2, DEL, v1 ]"); 12458cd4ab8303620197cf24282ae8639060efbb326egabor@google.com ASSERT_OK(dbfull()->TEST_CompactMemTable()); // Moves to level last-2 1246179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_EQ(AllEntriesFor("foo"), "[ v2, DEL, v1 ]"); 12475fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com Slice z("z"); 12485fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com dbfull()->TEST_CompactRange(last-2, NULL, &z); 1249179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // DEL eliminated, but v1 remains because we aren't compacting that level 1250179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // (DEL can be eliminated because v2 hides v1). 1251179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_EQ(AllEntriesFor("foo"), "[ v2, v1 ]"); 12525fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com dbfull()->TEST_CompactRange(last-1, NULL, NULL); 12538cd4ab8303620197cf24282ae8639060efbb326egabor@google.com // Merging last-1 w/ last, so we are the base level for "foo", so 12548cd4ab8303620197cf24282ae8639060efbb326egabor@google.com // DEL is removed. (as is v1). 1255179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_EQ(AllEntriesFor("foo"), "[ v2 ]"); 1256179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 1257179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 1258179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgTEST(DBTest, DeletionMarkers2) { 1259179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Put("foo", "v1"); 1260179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_OK(dbfull()->TEST_CompactMemTable()); 1261917b88dd720b6e658c1fd7812bc61c605f315124gabor@google.com const int last = config::kMaxMemCompactLevel; 12628cd4ab8303620197cf24282ae8639060efbb326egabor@google.com ASSERT_EQ(NumTableFilesAtLevel(last), 1); // foo => v1 is now in last level 12638cd4ab8303620197cf24282ae8639060efbb326egabor@google.com 12648cd4ab8303620197cf24282ae8639060efbb326egabor@google.com // Place a table at level last-1 to prevent merging with preceding mutation 12658cd4ab8303620197cf24282ae8639060efbb326egabor@google.com Put("a", "begin"); 12668cd4ab8303620197cf24282ae8639060efbb326egabor@google.com Put("z", "end"); 12678cd4ab8303620197cf24282ae8639060efbb326egabor@google.com dbfull()->TEST_CompactMemTable(); 12688cd4ab8303620197cf24282ae8639060efbb326egabor@google.com ASSERT_EQ(NumTableFilesAtLevel(last), 1); 12698cd4ab8303620197cf24282ae8639060efbb326egabor@google.com ASSERT_EQ(NumTableFilesAtLevel(last-1), 1); 12708cd4ab8303620197cf24282ae8639060efbb326egabor@google.com 1271179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Delete("foo"); 1272179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_EQ(AllEntriesFor("foo"), "[ DEL, v1 ]"); 12738cd4ab8303620197cf24282ae8639060efbb326egabor@google.com ASSERT_OK(dbfull()->TEST_CompactMemTable()); // Moves to level last-2 1274179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_EQ(AllEntriesFor("foo"), "[ DEL, v1 ]"); 12755fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com dbfull()->TEST_CompactRange(last-2, NULL, NULL); 12768cd4ab8303620197cf24282ae8639060efbb326egabor@google.com // DEL kept: "last" file overlaps 1277179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_EQ(AllEntriesFor("foo"), "[ DEL, v1 ]"); 12785fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com dbfull()->TEST_CompactRange(last-1, NULL, NULL); 12798cd4ab8303620197cf24282ae8639060efbb326egabor@google.com // Merging last-1 w/ last, so we are the base level for "foo", so 12808cd4ab8303620197cf24282ae8639060efbb326egabor@google.com // DEL is removed. (as is v1). 1281179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_EQ(AllEntriesFor("foo"), "[ ]"); 1282179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 1283179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 12845fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.comTEST(DBTest, OverlapInLevel0) { 128599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com do { 128699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ(config::kMaxMemCompactLevel, 2) << "Fix test to match config"; 12875fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com 128899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // Fill levels 1 and 2 to disable the pushing of new memtables to levels > 0. 128999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put("100", "v100")); 129099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put("999", "v999")); 129199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com dbfull()->TEST_CompactMemTable(); 129299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Delete("100")); 129399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Delete("999")); 129499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com dbfull()->TEST_CompactMemTable(); 129599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("0,1,1", FilesPerLevel()); 129699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com 129799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // Make files spanning the following ranges in level-0: 129899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // files[0] 200 .. 900 129999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // files[1] 300 .. 500 130099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // Note that files are sorted by smallest key. 130199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put("300", "v300")); 130299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put("500", "v500")); 130399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com dbfull()->TEST_CompactMemTable(); 130499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put("200", "v200")); 130599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put("600", "v600")); 130699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put("900", "v900")); 130799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com dbfull()->TEST_CompactMemTable(); 130899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("2,1,1", FilesPerLevel()); 13095fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com 131099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // Compact away the placeholder files we created initially 131199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com dbfull()->TEST_CompactRange(1, NULL, NULL); 131299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com dbfull()->TEST_CompactRange(2, NULL, NULL); 131399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("2", FilesPerLevel()); 13145fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com 131599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // Do a memtable compaction. Before bug-fix, the compaction would 131699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // not detect the overlap with level-0 files and would incorrectly place 131799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // the deletion in a deeper level. 131899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Delete("600")); 131999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com dbfull()->TEST_CompactMemTable(); 132099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("3", FilesPerLevel()); 132199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("NOT_FOUND", Get("600")); 132299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } while (ChangeOptions()); 13235fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com} 13245fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com 132545b9940be332834440bd5299419f396e38085ebehans@chromium.orgTEST(DBTest, L0_CompactionBug_Issue44_a) { 132699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Reopen(); 132799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put("b", "v")); 132899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Reopen(); 132999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Delete("b")); 133099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Delete("a")); 133199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Reopen(); 133299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Delete("a")); 133399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Reopen(); 133499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put("a", "v")); 133599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Reopen(); 133699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Reopen(); 133799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("(a->v)", Contents()); 133811042098fe3e5a16ad70c388bb5914a907ae3faedgrogan@chromium.org DelayMilliseconds(1000); // Wait for compaction to finish 133999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("(a->v)", Contents()); 134045b9940be332834440bd5299419f396e38085ebehans@chromium.org} 134145b9940be332834440bd5299419f396e38085ebehans@chromium.org 134245b9940be332834440bd5299419f396e38085ebehans@chromium.orgTEST(DBTest, L0_CompactionBug_Issue44_b) { 134399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Reopen(); 134499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Put("",""); 134599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Reopen(); 134699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Delete("e"); 134799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Put("",""); 134899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Reopen(); 134999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Put("c", "cv"); 135099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Reopen(); 135199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Put("",""); 135299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Reopen(); 135399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Put("",""); 135411042098fe3e5a16ad70c388bb5914a907ae3faedgrogan@chromium.org DelayMilliseconds(1000); // Wait for compaction to finish 135599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Reopen(); 135699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Put("d","dv"); 135799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Reopen(); 135899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Put("",""); 135999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Reopen(); 136099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Delete("d"); 136199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Delete("b"); 136299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Reopen(); 136399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("(->)(c->cv)", Contents()); 136411042098fe3e5a16ad70c388bb5914a907ae3faedgrogan@chromium.org DelayMilliseconds(1000); // Wait for compaction to finish 136599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("(->)(c->cv)", Contents()); 136645b9940be332834440bd5299419f396e38085ebehans@chromium.org} 136745b9940be332834440bd5299419f396e38085ebehans@chromium.org 1368179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgTEST(DBTest, ComparatorCheck) { 1369179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org class NewComparator : public Comparator { 1370179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org public: 1371179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org virtual const char* Name() const { return "leveldb.NewComparator"; } 1372179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org virtual int Compare(const Slice& a, const Slice& b) const { 1373179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return BytewiseComparator()->Compare(a, b); 1374179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 1375179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org virtual void FindShortestSeparator(std::string* s, const Slice& l) const { 1376179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org BytewiseComparator()->FindShortestSeparator(s, l); 1377179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 1378179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org virtual void FindShortSuccessor(std::string* key) const { 1379179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org BytewiseComparator()->FindShortSuccessor(key); 1380179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 1381179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org }; 1382179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org NewComparator cmp; 138399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Options new_options = CurrentOptions(); 1384179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org new_options.comparator = &cmp; 1385179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Status s = TryReopen(&new_options); 1386179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_TRUE(!s.ok()); 1387179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_TRUE(s.ToString().find("comparator") != std::string::npos) 1388179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org << s.ToString(); 1389179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 1390179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 139145b9940be332834440bd5299419f396e38085ebehans@chromium.orgTEST(DBTest, CustomComparator) { 139245b9940be332834440bd5299419f396e38085ebehans@chromium.org class NumberComparator : public Comparator { 139345b9940be332834440bd5299419f396e38085ebehans@chromium.org public: 139445b9940be332834440bd5299419f396e38085ebehans@chromium.org virtual const char* Name() const { return "test.NumberComparator"; } 139545b9940be332834440bd5299419f396e38085ebehans@chromium.org virtual int Compare(const Slice& a, const Slice& b) const { 1396ac271d8b01dd3a1b6d57b1a4a0e0d28e00f67780hans@chromium.org return ToNumber(a) - ToNumber(b); 1397ac271d8b01dd3a1b6d57b1a4a0e0d28e00f67780hans@chromium.org } 1398ac271d8b01dd3a1b6d57b1a4a0e0d28e00f67780hans@chromium.org virtual void FindShortestSeparator(std::string* s, const Slice& l) const { 1399ac271d8b01dd3a1b6d57b1a4a0e0d28e00f67780hans@chromium.org ToNumber(*s); // Check format 1400ac271d8b01dd3a1b6d57b1a4a0e0d28e00f67780hans@chromium.org ToNumber(l); // Check format 1401ac271d8b01dd3a1b6d57b1a4a0e0d28e00f67780hans@chromium.org } 1402ac271d8b01dd3a1b6d57b1a4a0e0d28e00f67780hans@chromium.org virtual void FindShortSuccessor(std::string* key) const { 1403ac271d8b01dd3a1b6d57b1a4a0e0d28e00f67780hans@chromium.org ToNumber(*key); // Check format 1404ac271d8b01dd3a1b6d57b1a4a0e0d28e00f67780hans@chromium.org } 1405ac271d8b01dd3a1b6d57b1a4a0e0d28e00f67780hans@chromium.org private: 1406ac271d8b01dd3a1b6d57b1a4a0e0d28e00f67780hans@chromium.org static int ToNumber(const Slice& x) { 1407ac271d8b01dd3a1b6d57b1a4a0e0d28e00f67780hans@chromium.org // Check that there are no extra characters. 1408ac271d8b01dd3a1b6d57b1a4a0e0d28e00f67780hans@chromium.org ASSERT_TRUE(x.size() >= 2 && x[0] == '[' && x[x.size()-1] == ']') 1409ac271d8b01dd3a1b6d57b1a4a0e0d28e00f67780hans@chromium.org << EscapeString(x); 1410ac271d8b01dd3a1b6d57b1a4a0e0d28e00f67780hans@chromium.org int val; 1411ac271d8b01dd3a1b6d57b1a4a0e0d28e00f67780hans@chromium.org char ignored; 1412ac271d8b01dd3a1b6d57b1a4a0e0d28e00f67780hans@chromium.org ASSERT_TRUE(sscanf(x.ToString().c_str(), "[%i]%c", &val, &ignored) == 1) 1413ac271d8b01dd3a1b6d57b1a4a0e0d28e00f67780hans@chromium.org << EscapeString(x); 1414ac271d8b01dd3a1b6d57b1a4a0e0d28e00f67780hans@chromium.org return val; 141545b9940be332834440bd5299419f396e38085ebehans@chromium.org } 141645b9940be332834440bd5299419f396e38085ebehans@chromium.org }; 141745b9940be332834440bd5299419f396e38085ebehans@chromium.org NumberComparator cmp; 141899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Options new_options = CurrentOptions(); 141945b9940be332834440bd5299419f396e38085ebehans@chromium.org new_options.create_if_missing = true; 142045b9940be332834440bd5299419f396e38085ebehans@chromium.org new_options.comparator = &cmp; 142199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com new_options.filter_policy = NULL; // Cannot use bloom filters 1422ac271d8b01dd3a1b6d57b1a4a0e0d28e00f67780hans@chromium.org new_options.write_buffer_size = 1000; // Compact more often 142345b9940be332834440bd5299419f396e38085ebehans@chromium.org DestroyAndReopen(&new_options); 1424ac271d8b01dd3a1b6d57b1a4a0e0d28e00f67780hans@chromium.org ASSERT_OK(Put("[10]", "ten")); 1425ac271d8b01dd3a1b6d57b1a4a0e0d28e00f67780hans@chromium.org ASSERT_OK(Put("[0x14]", "twenty")); 142645b9940be332834440bd5299419f396e38085ebehans@chromium.org for (int i = 0; i < 2; i++) { 1427ac271d8b01dd3a1b6d57b1a4a0e0d28e00f67780hans@chromium.org ASSERT_EQ("ten", Get("[10]")); 1428ac271d8b01dd3a1b6d57b1a4a0e0d28e00f67780hans@chromium.org ASSERT_EQ("ten", Get("[0xa]")); 1429ac271d8b01dd3a1b6d57b1a4a0e0d28e00f67780hans@chromium.org ASSERT_EQ("twenty", Get("[20]")); 1430ac271d8b01dd3a1b6d57b1a4a0e0d28e00f67780hans@chromium.org ASSERT_EQ("twenty", Get("[0x14]")); 143199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("NOT_FOUND", Get("[15]")); 143299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("NOT_FOUND", Get("[0xf]")); 1433ac271d8b01dd3a1b6d57b1a4a0e0d28e00f67780hans@chromium.org Compact("[0]", "[9999]"); 1434ac271d8b01dd3a1b6d57b1a4a0e0d28e00f67780hans@chromium.org } 1435ac271d8b01dd3a1b6d57b1a4a0e0d28e00f67780hans@chromium.org 1436ac271d8b01dd3a1b6d57b1a4a0e0d28e00f67780hans@chromium.org for (int run = 0; run < 2; run++) { 1437ac271d8b01dd3a1b6d57b1a4a0e0d28e00f67780hans@chromium.org for (int i = 0; i < 1000; i++) { 1438ac271d8b01dd3a1b6d57b1a4a0e0d28e00f67780hans@chromium.org char buf[100]; 1439ac271d8b01dd3a1b6d57b1a4a0e0d28e00f67780hans@chromium.org snprintf(buf, sizeof(buf), "[%d]", i*10); 1440ac271d8b01dd3a1b6d57b1a4a0e0d28e00f67780hans@chromium.org ASSERT_OK(Put(buf, buf)); 1441ac271d8b01dd3a1b6d57b1a4a0e0d28e00f67780hans@chromium.org } 1442ac271d8b01dd3a1b6d57b1a4a0e0d28e00f67780hans@chromium.org Compact("[0]", "[1000000]"); 144345b9940be332834440bd5299419f396e38085ebehans@chromium.org } 144445b9940be332834440bd5299419f396e38085ebehans@chromium.org} 144545b9940be332834440bd5299419f396e38085ebehans@chromium.org 14465fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.comTEST(DBTest, ManualCompaction) { 14475fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com ASSERT_EQ(config::kMaxMemCompactLevel, 2) 14485fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com << "Need to update this test to match kMaxMemCompactLevel"; 14495fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com 14505fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com MakeTables(3, "p", "q"); 14515fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com ASSERT_EQ("1,1,1", FilesPerLevel()); 14525fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com 14535fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com // Compaction range falls before files 14545fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com Compact("", "c"); 14555fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com ASSERT_EQ("1,1,1", FilesPerLevel()); 14565fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com 14575fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com // Compaction range falls after files 14585fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com Compact("r", "z"); 14595fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com ASSERT_EQ("1,1,1", FilesPerLevel()); 14605fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com 14615fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com // Compaction range overlaps files 14625fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com Compact("p1", "p9"); 14635fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com ASSERT_EQ("0,0,1", FilesPerLevel()); 14645fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com 14655fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com // Populate a different range 14665fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com MakeTables(3, "c", "e"); 14675fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com ASSERT_EQ("1,1,2", FilesPerLevel()); 14685fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com 14695fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com // Compact just the new range 14705fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com Compact("b", "f"); 14715fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com ASSERT_EQ("0,0,2", FilesPerLevel()); 14725fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com 14735fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com // Compact all 14745fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com MakeTables(1, "a", "z"); 14755fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com ASSERT_EQ("0,1,2", FilesPerLevel()); 14765fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com db_->CompactRange(NULL, NULL); 14775fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com ASSERT_EQ("0,0,1", FilesPerLevel()); 14785fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com} 14795fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com 1480179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgTEST(DBTest, DBOpen_Options) { 1481179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org std::string dbname = test::TmpDir() + "/db_options_test"; 1482179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org DestroyDB(dbname, Options()); 1483179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 1484179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // Does not exist, and create_if_missing == false: error 1485179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org DB* db = NULL; 1486179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Options opts; 1487179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org opts.create_if_missing = false; 1488179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Status s = DB::Open(opts, dbname, &db); 1489179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_TRUE(strstr(s.ToString().c_str(), "does not exist") != NULL); 1490179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_TRUE(db == NULL); 1491179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 1492179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // Does not exist, and create_if_missing == true: OK 1493179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org opts.create_if_missing = true; 1494179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org s = DB::Open(opts, dbname, &db); 1495179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_OK(s); 1496179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_TRUE(db != NULL); 1497179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 1498179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org delete db; 1499179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org db = NULL; 1500179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 1501179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // Does exist, and error_if_exists == true: error 1502179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org opts.create_if_missing = false; 1503179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org opts.error_if_exists = true; 1504179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org s = DB::Open(opts, dbname, &db); 1505179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_TRUE(strstr(s.ToString().c_str(), "exists") != NULL); 1506179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_TRUE(db == NULL); 1507179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 1508179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // Does exist, and error_if_exists == false: OK 1509179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org opts.create_if_missing = true; 1510179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org opts.error_if_exists = false; 1511179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org s = DB::Open(opts, dbname, &db); 1512179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_OK(s); 1513179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ASSERT_TRUE(db != NULL); 1514179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 1515179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org delete db; 1516179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org db = NULL; 1517179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 1518179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 151929c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.orgTEST(DBTest, Locking) { 152029c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org DB* db2 = NULL; 152129c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org Status s = DB::Open(CurrentOptions(), dbname_, &db2); 152229c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org ASSERT_TRUE(!s.ok()) << "Locking did not prevent re-opening db"; 152329c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org} 152429c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org 1525e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com// Check that number of files does not grow when we are out of space 1526e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.comTEST(DBTest, NoSpace) { 152799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Options options = CurrentOptions(); 1528e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com options.env = env_; 1529e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com Reopen(&options); 1530e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com 1531e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com ASSERT_OK(Put("foo", "v1")); 1532e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com ASSERT_EQ("v1", Get("foo")); 1533e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com Compact("a", "z"); 1534e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com const int num_files = CountFiles(); 1535e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com env_->no_space_.Release_Store(env_); // Force out-of-space errors 15364935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org for (int i = 0; i < 10; i++) { 1537e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com for (int level = 0; level < config::kNumLevels-1; level++) { 1538e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com dbfull()->TEST_CompactRange(level, NULL, NULL); 1539e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com } 1540e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com } 1541e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com env_->no_space_.Release_Store(NULL); 1542158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com ASSERT_LT(CountFiles(), num_files + 3); 154311042098fe3e5a16ad70c388bb5914a907ae3faedgrogan@chromium.org} 154411042098fe3e5a16ad70c388bb5914a907ae3faedgrogan@chromium.org 1545158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.comTEST(DBTest, NonWritableFileSystem) { 1546158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com Options options = CurrentOptions(); 1547158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com options.write_buffer_size = 1000; 1548158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com options.env = env_; 1549158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com Reopen(&options); 1550158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com ASSERT_OK(Put("foo", "v1")); 1551158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com env_->non_writable_.Release_Store(env_); // Force errors for new files 1552158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com std::string big(100000, 'x'); 1553158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com int errors = 0; 1554158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com for (int i = 0; i < 20; i++) { 1555158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com fprintf(stderr, "iter %d; errors %d\n", i, errors); 1556158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com if (!Put("foo", big).ok()) { 1557158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com errors++; 155811042098fe3e5a16ad70c388bb5914a907ae3faedgrogan@chromium.org DelayMilliseconds(100); 1559158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com } 1560158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com } 1561158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com ASSERT_GT(errors, 0); 1562158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com env_->non_writable_.Release_Store(NULL); 1563e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com} 1564e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com 15654935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.orgTEST(DBTest, WriteSyncError) { 15664935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org // Check that log sync errors cause the DB to disallow future writes. 15674935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org 15684935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org // (a) Cause log sync calls to fail 15694935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org Options options = CurrentOptions(); 15704935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org options.env = env_; 15714935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org Reopen(&options); 15724935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org env_->data_sync_error_.Release_Store(env_); 15734935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org 15744935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org // (b) Normal write should succeed 15754935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org WriteOptions w; 15764935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org ASSERT_OK(db_->Put(w, "k1", "v1")); 15774935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org ASSERT_EQ("v1", Get("k1")); 15784935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org 15794935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org // (c) Do a sync write; should fail 15804935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org w.sync = true; 15814935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org ASSERT_TRUE(!db_->Put(w, "k2", "v2").ok()); 15824935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org ASSERT_EQ("v1", Get("k1")); 15834935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org ASSERT_EQ("NOT_FOUND", Get("k2")); 15844935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org 15854935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org // (d) make sync behave normally 15864935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org env_->data_sync_error_.Release_Store(NULL); 15874935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org 15884935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org // (e) Do a non-sync write; should fail 15894935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org w.sync = false; 15904935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org ASSERT_TRUE(!db_->Put(w, "k3", "v3").ok()); 15914935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org ASSERT_EQ("v1", Get("k1")); 15924935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org ASSERT_EQ("NOT_FOUND", Get("k2")); 15934935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org ASSERT_EQ("NOT_FOUND", Get("k3")); 15944935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org} 15954935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org 159685e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.orgTEST(DBTest, ManifestWriteError) { 159785e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org // Test for the following problem: 159885e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org // (a) Compaction produces file F 159985e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org // (b) Log record containing F is written to MANIFEST file, but Sync() fails 160085e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org // (c) GC deletes F 160185e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org // (d) After reopening DB, reads fail since deleted F is named in log record 160285e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org 160385e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org // We iterate twice. In the second iteration, everything is the 160485e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org // same except the log record never makes it to the MANIFEST file. 160585e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org for (int iter = 0; iter < 2; iter++) { 160685e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org port::AtomicPointer* error_type = (iter == 0) 160785e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org ? &env_->manifest_sync_error_ 160885e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org : &env_->manifest_write_error_; 160985e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org 161085e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org // Insert foo=>bar mapping 161185e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org Options options = CurrentOptions(); 161285e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org options.env = env_; 161385e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org options.create_if_missing = true; 161485e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org options.error_if_exists = false; 161585e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org DestroyAndReopen(&options); 161685e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org ASSERT_OK(Put("foo", "bar")); 161785e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org ASSERT_EQ("bar", Get("foo")); 161885e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org 161985e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org // Memtable compaction (will succeed) 162085e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org dbfull()->TEST_CompactMemTable(); 162185e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org ASSERT_EQ("bar", Get("foo")); 162285e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org const int last = config::kMaxMemCompactLevel; 162385e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org ASSERT_EQ(NumTableFilesAtLevel(last), 1); // foo=>bar is now in last level 162485e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org 162585e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org // Merging compaction (will fail) 162685e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org error_type->Release_Store(env_); 162785e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org dbfull()->TEST_CompactRange(last, NULL, NULL); // Should fail 162885e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org ASSERT_EQ("bar", Get("foo")); 162985e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org 163085e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org // Recovery: should not lose data 163185e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org error_type->Release_Store(NULL); 163285e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org Reopen(&options); 163385e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org ASSERT_EQ("bar", Get("foo")); 163485e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org } 163585e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org} 163685e27d04530c0323957f28c3f47a7d9f6efeceb0dgrogan@chromium.org 1637bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.orgTEST(DBTest, MissingSSTFile) { 1638bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org ASSERT_OK(Put("foo", "bar")); 1639bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org ASSERT_EQ("bar", Get("foo")); 1640bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org 1641bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org // Dump the memtable to disk. 1642bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org dbfull()->TEST_CompactMemTable(); 1643bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org ASSERT_EQ("bar", Get("foo")); 1644bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org 164511042098fe3e5a16ad70c388bb5914a907ae3faedgrogan@chromium.org Close(); 1646bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org ASSERT_TRUE(DeleteAnSSTFile()); 1647bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org Options options = CurrentOptions(); 1648bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org options.paranoid_checks = true; 1649bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org Status s = TryReopen(&options); 1650bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org ASSERT_TRUE(!s.ok()); 1651bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org ASSERT_TRUE(s.ToString().find("issing") != std::string::npos) 1652bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org << s.ToString(); 1653bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org} 1654bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org 16552d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.orgTEST(DBTest, StillReadSST) { 16562d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.org ASSERT_OK(Put("foo", "bar")); 16572d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.org ASSERT_EQ("bar", Get("foo")); 16582d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.org 16592d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.org // Dump the memtable to disk. 16602d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.org dbfull()->TEST_CompactMemTable(); 16612d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.org ASSERT_EQ("bar", Get("foo")); 16622d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.org Close(); 16632d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.org ASSERT_GT(RenameLDBToSST(), 0); 16642d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.org Options options = CurrentOptions(); 16652d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.org options.paranoid_checks = true; 16662d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.org Status s = TryReopen(&options); 16672d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.org ASSERT_TRUE(s.ok()); 16682d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.org ASSERT_EQ("bar", Get("foo")); 16692d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.org} 16702d749ea62f0e47281e82794c8e00eb588cd66616dgrogan@chromium.org 1671e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.comTEST(DBTest, FilesDeletedAfterCompaction) { 1672e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com ASSERT_OK(Put("foo", "v2")); 1673e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com Compact("a", "z"); 1674e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com const int num_files = CountFiles(); 1675e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com for (int i = 0; i < 10; i++) { 1676e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com ASSERT_OK(Put("foo", "v2")); 1677e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com Compact("a", "z"); 1678e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com } 1679e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com ASSERT_EQ(CountFiles(), num_files); 1680e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com} 1681e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com 168299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.comTEST(DBTest, BloomFilter) { 168399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com env_->count_random_reads_ = true; 168499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Options options = CurrentOptions(); 168599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com options.env = env_; 168699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com options.block_cache = NewLRUCache(0); // Prevent cache hits 168799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com options.filter_policy = NewBloomFilterPolicy(10); 168899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Reopen(&options); 168999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com 169099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // Populate multiple layers 169199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com const int N = 10000; 169299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com for (int i = 0; i < N; i++) { 169399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put(Key(i), Key(i))); 169499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } 169599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Compact("a", "z"); 169699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com for (int i = 0; i < N; i += 100) { 169799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(Put(Key(i), Key(i))); 169899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } 169999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com dbfull()->TEST_CompactMemTable(); 170099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com 170199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // Prevent auto compactions triggered by seeks 17024935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org env_->delay_data_sync_.Release_Store(env_); 170399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com 170499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // Lookup present keys. Should rarely read from small sstable. 170599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com env_->random_read_counter_.Reset(); 170699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com for (int i = 0; i < N; i++) { 170799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ(Key(i), Get(Key(i))); 170899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } 170999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com int reads = env_->random_read_counter_.Read(); 171099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com fprintf(stderr, "%d present => %d reads\n", N, reads); 171199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_GE(reads, N); 171299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_LE(reads, N + 2*N/100); 171399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com 171499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // Lookup present keys. Should rarely read from either sstable. 171599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com env_->random_read_counter_.Reset(); 171699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com for (int i = 0; i < N; i++) { 171799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_EQ("NOT_FOUND", Get(Key(i) + ".missing")); 171899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } 171999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com reads = env_->random_read_counter_.Read(); 172099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com fprintf(stderr, "%d missing => %d reads\n", N, reads); 172199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_LE(reads, 3*N/100); 172299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com 17234935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org env_->delay_data_sync_.Release_Store(NULL); 172499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Close(); 172599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com delete options.block_cache; 172699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com delete options.filter_policy; 172799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com} 172899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com 1729c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org// Multi-threaded test: 1730c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.orgnamespace { 1731c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org 1732c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.orgstatic const int kNumThreads = 4; 1733c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.orgstatic const int kTestSeconds = 10; 1734c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.orgstatic const int kNumKeys = 1000; 1735c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org 1736c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.orgstruct MTState { 1737c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org DBTest* test; 1738c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org port::AtomicPointer stop; 1739c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org port::AtomicPointer counter[kNumThreads]; 1740c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org port::AtomicPointer thread_done[kNumThreads]; 1741c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org}; 1742c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org 1743c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.orgstruct MTThread { 1744c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org MTState* state; 1745c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org int id; 1746c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org}; 1747c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org 1748c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.orgstatic void MTThreadBody(void* arg) { 1749c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org MTThread* t = reinterpret_cast<MTThread*>(arg); 1750e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com int id = t->id; 1751c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org DB* db = t->state->test->db_; 1752c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org uintptr_t counter = 0; 1753e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com fprintf(stderr, "... starting thread %d\n", id); 1754e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com Random rnd(1000 + id); 1755c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org std::string value; 1756c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org char valbuf[1500]; 1757c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org while (t->state->stop.Acquire_Load() == NULL) { 1758e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com t->state->counter[id].Release_Store(reinterpret_cast<void*>(counter)); 1759c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org 1760c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org int key = rnd.Uniform(kNumKeys); 1761c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org char keybuf[20]; 1762c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org snprintf(keybuf, sizeof(keybuf), "%016d", key); 1763c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org 1764c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org if (rnd.OneIn(2)) { 1765c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org // Write values of the form <key, my id, counter>. 1766c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org // We add some padding for force compactions. 1767c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org snprintf(valbuf, sizeof(valbuf), "%d.%d.%-1000d", 1768e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com key, id, static_cast<int>(counter)); 1769c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org ASSERT_OK(db->Put(WriteOptions(), Slice(keybuf), Slice(valbuf))); 1770c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org } else { 1771c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org // Read a value and verify that it matches the pattern written above. 1772c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org Status s = db->Get(ReadOptions(), Slice(keybuf), &value); 1773c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org if (s.IsNotFound()) { 1774c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org // Key has not yet been written 1775c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org } else { 1776c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org // Check that the writer thread counter is >= the counter in the value 1777c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org ASSERT_OK(s); 1778c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org int k, w, c; 1779c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org ASSERT_EQ(3, sscanf(value.c_str(), "%d.%d.%d", &k, &w, &c)) << value; 1780c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org ASSERT_EQ(k, key); 1781c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org ASSERT_GE(w, 0); 1782c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org ASSERT_LT(w, kNumThreads); 17834935bf087b28aa308c0a820720b85ef695e236aedgrogan@chromium.org ASSERT_LE(static_cast<uintptr_t>(c), reinterpret_cast<uintptr_t>( 1784c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org t->state->counter[w].Acquire_Load())); 1785c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org } 1786c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org } 1787c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org counter++; 1788c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org } 1789e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com t->state->thread_done[id].Release_Store(t); 1790e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com fprintf(stderr, "... stopping thread %d after %d ops\n", id, int(counter)); 1791c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org} 1792c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org 179345b9940be332834440bd5299419f396e38085ebehans@chromium.org} // namespace 1794c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org 1795c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.orgTEST(DBTest, MultiThreaded) { 179699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com do { 179799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // Initialize state 179899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com MTState mt; 179999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com mt.test = this; 180099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com mt.stop.Release_Store(0); 180199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com for (int id = 0; id < kNumThreads; id++) { 180299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com mt.counter[id].Release_Store(0); 180399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com mt.thread_done[id].Release_Store(0); 180499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } 1805c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org 180699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // Start threads 180799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com MTThread thread[kNumThreads]; 180899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com for (int id = 0; id < kNumThreads; id++) { 180999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com thread[id].state = &mt; 181099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com thread[id].id = id; 181199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com env_->StartThread(MTThreadBody, &thread[id]); 181299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } 1813c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org 181499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // Let them run for a while 181511042098fe3e5a16ad70c388bb5914a907ae3faedgrogan@chromium.org DelayMilliseconds(kTestSeconds * 1000); 1816c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org 181799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // Stop the threads and wait for them to finish 181899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com mt.stop.Release_Store(&mt); 181999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com for (int id = 0; id < kNumThreads; id++) { 182099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com while (mt.thread_done[id].Acquire_Load() == NULL) { 182111042098fe3e5a16ad70c388bb5914a907ae3faedgrogan@chromium.org DelayMilliseconds(100); 182299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } 1823c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org } 182499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } while (ChangeOptions()); 1825c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org} 1826c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org 1827a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.orgnamespace { 1828a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.orgtypedef std::map<std::string, std::string> KVMap; 1829a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org} 1830a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org 1831179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgclass ModelDB: public DB { 1832179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org public: 1833a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org class ModelSnapshot : public Snapshot { 1834a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org public: 1835a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org KVMap map_; 1836a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org }; 1837a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org 1838179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org explicit ModelDB(const Options& options): options_(options) { } 1839179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ~ModelDB() { } 1840179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org virtual Status Put(const WriteOptions& o, const Slice& k, const Slice& v) { 1841179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return DB::Put(o, k, v); 1842179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 1843179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org virtual Status Delete(const WriteOptions& o, const Slice& key) { 1844179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return DB::Delete(o, key); 1845179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 1846179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org virtual Status Get(const ReadOptions& options, 1847179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org const Slice& key, std::string* value) { 1848179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org assert(false); // Not implemented 1849179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return Status::NotFound(key); 1850179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 1851179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org virtual Iterator* NewIterator(const ReadOptions& options) { 1852179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (options.snapshot == NULL) { 1853179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org KVMap* saved = new KVMap; 1854179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org *saved = map_; 1855179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return new ModelIter(saved, true); 1856179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } else { 1857179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org const KVMap* snapshot_state = 1858a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org &(reinterpret_cast<const ModelSnapshot*>(options.snapshot)->map_); 1859179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return new ModelIter(snapshot_state, false); 1860179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 1861179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 1862179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org virtual const Snapshot* GetSnapshot() { 1863a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org ModelSnapshot* snapshot = new ModelSnapshot; 1864a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org snapshot->map_ = map_; 1865a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org return snapshot; 1866179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 1867179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 1868179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org virtual void ReleaseSnapshot(const Snapshot* snapshot) { 1869a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org delete reinterpret_cast<const ModelSnapshot*>(snapshot); 1870179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 1871179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org virtual Status Write(const WriteOptions& options, WriteBatch* batch) { 1872a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org class Handler : public WriteBatch::Handler { 1873a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org public: 1874a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org KVMap* map_; 1875a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org virtual void Put(const Slice& key, const Slice& value) { 1876a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org (*map_)[key.ToString()] = value.ToString(); 1877179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 1878a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org virtual void Delete(const Slice& key) { 1879a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org map_->erase(key.ToString()); 1880a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org } 1881a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org }; 1882a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org Handler handler; 1883a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org handler.map_ = &map_; 1884a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org return batch->Iterate(&handler); 1885179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 1886179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 188795e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org virtual bool GetProperty(const Slice& property, std::string* value) { 1888179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return false; 1889179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 1890179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org virtual void GetApproximateSizes(const Range* r, int n, uint64_t* sizes) { 1891179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org for (int i = 0; i < n; i++) { 1892179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org sizes[i] = 0; 1893179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 1894179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 18955fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com virtual void CompactRange(const Slice* start, const Slice* end) { 18965fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com } 18975fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com 1898179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org private: 1899179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org class ModelIter: public Iterator { 1900179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org public: 1901179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ModelIter(const KVMap* map, bool owned) 1902179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org : map_(map), owned_(owned), iter_(map_->end()) { 1903179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 1904179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ~ModelIter() { 1905179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (owned_) delete map_; 1906179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 1907179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org virtual bool Valid() const { return iter_ != map_->end(); } 1908179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org virtual void SeekToFirst() { iter_ = map_->begin(); } 1909179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org virtual void SeekToLast() { 1910179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (map_->empty()) { 1911179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org iter_ = map_->end(); 1912179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } else { 1913179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org iter_ = map_->find(map_->rbegin()->first); 1914179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 1915179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 1916179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org virtual void Seek(const Slice& k) { 1917179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org iter_ = map_->lower_bound(k.ToString()); 1918179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 1919179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org virtual void Next() { ++iter_; } 1920179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org virtual void Prev() { --iter_; } 1921179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org virtual Slice key() const { return iter_->first; } 1922179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org virtual Slice value() const { return iter_->second; } 1923179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org virtual Status status() const { return Status::OK(); } 1924179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org private: 1925179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org const KVMap* const map_; 1926179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org const bool owned_; // Do we own map_ 1927179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org KVMap::const_iterator iter_; 1928179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org }; 1929179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org const Options options_; 1930179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org KVMap map_; 1931179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}; 1932179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 1933179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgstatic std::string RandomKey(Random* rnd) { 1934179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org int len = (rnd->OneIn(3) 1935179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ? 1 // Short sometimes to encourage collisions 1936179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org : (rnd->OneIn(100) ? rnd->Skewed(10) : rnd->Uniform(10))); 1937179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return test::RandomKey(rnd, len); 1938179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 1939179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 1940179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgstatic bool CompareIterators(int step, 1941179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org DB* model, 1942179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org DB* db, 1943179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org const Snapshot* model_snap, 1944179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org const Snapshot* db_snap) { 1945179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ReadOptions options; 1946179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org options.snapshot = model_snap; 1947179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Iterator* miter = model->NewIterator(options); 1948179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org options.snapshot = db_snap; 1949179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Iterator* dbiter = db->NewIterator(options); 1950179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org bool ok = true; 1951179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org int count = 0; 1952179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org for (miter->SeekToFirst(), dbiter->SeekToFirst(); 1953179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ok && miter->Valid() && dbiter->Valid(); 1954179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org miter->Next(), dbiter->Next()) { 1955179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org count++; 1956179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (miter->key().compare(dbiter->key()) != 0) { 1957179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org fprintf(stderr, "step %d: Key mismatch: '%s' vs. '%s'\n", 1958179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org step, 1959179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org EscapeString(miter->key()).c_str(), 1960179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org EscapeString(dbiter->key()).c_str()); 1961179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ok = false; 1962179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org break; 1963179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 1964179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 1965179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (miter->value().compare(dbiter->value()) != 0) { 1966179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org fprintf(stderr, "step %d: Value mismatch for key '%s': '%s' vs. '%s'\n", 1967179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org step, 1968179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org EscapeString(miter->key()).c_str(), 1969179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org EscapeString(miter->value()).c_str(), 1970179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org EscapeString(miter->value()).c_str()); 1971179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ok = false; 1972179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 1973179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 1974179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 1975179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (ok) { 1976179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (miter->Valid() != dbiter->Valid()) { 1977179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org fprintf(stderr, "step %d: Mismatch at end of iterators: %d vs. %d\n", 1978179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org step, miter->Valid(), dbiter->Valid()); 1979179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ok = false; 1980179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 1981179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 1982179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org fprintf(stderr, "%d entries compared: ok=%d\n", count, ok); 1983179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org delete miter; 1984179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org delete dbiter; 1985179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return ok; 1986179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 1987179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 1988179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgTEST(DBTest, Randomized) { 1989179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Random rnd(test::RandomSeed()); 199099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com do { 199199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ModelDB model(CurrentOptions()); 199299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com const int N = 10000; 199399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com const Snapshot* model_snap = NULL; 199499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com const Snapshot* db_snap = NULL; 199599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com std::string k, v; 199699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com for (int step = 0; step < N; step++) { 199799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com if (step % 100 == 0) { 199899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com fprintf(stderr, "Step %d of %d\n", step, N); 199999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } 200099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // TODO(sanjay): Test Get() works 200199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com int p = rnd.Uniform(100); 200299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com if (p < 45) { // Put 200399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com k = RandomKey(&rnd); 200499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com v = RandomString(&rnd, 200599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com rnd.OneIn(20) 200699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ? 100 + rnd.Uniform(100) 200799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com : rnd.Uniform(8)); 200899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(model.Put(WriteOptions(), k, v)); 200999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(db_->Put(WriteOptions(), k, v)); 201099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com 201199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } else if (p < 90) { // Delete 201299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com k = RandomKey(&rnd); 201399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(model.Delete(WriteOptions(), k)); 201499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(db_->Delete(WriteOptions(), k)); 201599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com 201699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com 201799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } else { // Multi-element batch 201899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com WriteBatch b; 201999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com const int num = rnd.Uniform(8); 202099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com for (int i = 0; i < num; i++) { 202199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com if (i == 0 || !rnd.OneIn(10)) { 202299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com k = RandomKey(&rnd); 202399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } else { 202499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // Periodically re-use the same key from the previous iter, so 202599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // we have multiple entries in the write batch for the same key 202699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } 202799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com if (rnd.OneIn(2)) { 202899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com v = RandomString(&rnd, rnd.Uniform(10)); 202999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com b.Put(k, v); 203099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } else { 203199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com b.Delete(k); 203299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } 2033179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 203499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(model.Write(WriteOptions(), &b)); 203599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_OK(db_->Write(WriteOptions(), &b)); 2036179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 2037179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 203899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com if ((step % 100) == 0) { 203999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_TRUE(CompareIterators(step, &model, db_, NULL, NULL)); 204099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_TRUE(CompareIterators(step, &model, db_, model_snap, db_snap)); 204199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // Save a snapshot from each DB this time that we'll use next 204299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // time we compare things, to make sure the current state is 204399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // preserved with the snapshot 204499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com if (model_snap != NULL) model.ReleaseSnapshot(model_snap); 204599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com if (db_snap != NULL) db_->ReleaseSnapshot(db_snap); 2046179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 204799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Reopen(); 204899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com ASSERT_TRUE(CompareIterators(step, &model, db_, NULL, NULL)); 2049179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 205099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com model_snap = model.GetSnapshot(); 205199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com db_snap = db_->GetSnapshot(); 205299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } 2053179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 205499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com if (model_snap != NULL) model.ReleaseSnapshot(model_snap); 205599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com if (db_snap != NULL) db_->ReleaseSnapshot(db_snap); 205699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } while (ChangeOptions()); 2057179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 2058179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 2059a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.orgstd::string MakeKey(unsigned int num) { 2060a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org char buf[30]; 2061a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org snprintf(buf, sizeof(buf), "%016u", num); 2062a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org return std::string(buf); 2063a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org} 2064a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org 2065a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.orgvoid BM_LogAndApply(int iters, int num_base_files) { 2066a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org std::string dbname = test::TmpDir() + "/leveldb_test_benchmark"; 2067a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org DestroyDB(dbname, Options()); 2068a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org 2069a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org DB* db = NULL; 2070a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org Options opts; 2071a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org opts.create_if_missing = true; 2072a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org Status s = DB::Open(opts, dbname, &db); 2073a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org ASSERT_OK(s); 2074a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org ASSERT_TRUE(db != NULL); 2075a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org 2076a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org delete db; 2077a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org db = NULL; 2078a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org 2079a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org Env* env = Env::Default(); 2080a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org 2081394a4b425a6a8aca3244fc26ec77c101a11a632cgabor@google.com port::Mutex mu; 2082394a4b425a6a8aca3244fc26ec77c101a11a632cgabor@google.com MutexLock l(&mu); 2083394a4b425a6a8aca3244fc26ec77c101a11a632cgabor@google.com 2084a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org InternalKeyComparator cmp(BytewiseComparator()); 2085a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org Options options; 2086a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org VersionSet vset(dbname, &options, NULL, &cmp); 2087a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org ASSERT_OK(vset.Recover()); 2088a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org VersionEdit vbase; 2089a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org uint64_t fnum = 1; 2090a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org for (int i = 0; i < num_base_files; i++) { 2091a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org InternalKey start(MakeKey(2*fnum), 1, kTypeValue); 2092a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org InternalKey limit(MakeKey(2*fnum+1), 1, kTypeDeletion); 2093a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org vbase.AddFile(2, fnum++, 1 /* file size */, start, limit); 2094a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org } 2095394a4b425a6a8aca3244fc26ec77c101a11a632cgabor@google.com ASSERT_OK(vset.LogAndApply(&vbase, &mu)); 2096a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org 2097a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org uint64_t start_micros = env->NowMicros(); 2098a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org 2099a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org for (int i = 0; i < iters; i++) { 2100a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org VersionEdit vedit; 2101a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org vedit.DeleteFile(2, fnum); 2102a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org InternalKey start(MakeKey(2*fnum), 1, kTypeValue); 2103a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org InternalKey limit(MakeKey(2*fnum+1), 1, kTypeDeletion); 2104a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org vedit.AddFile(2, fnum++, 1 /* file size */, start, limit); 2105394a4b425a6a8aca3244fc26ec77c101a11a632cgabor@google.com vset.LogAndApply(&vedit, &mu); 2106a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org } 2107a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org uint64_t stop_micros = env->NowMicros(); 2108a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org unsigned int us = stop_micros - start_micros; 2109a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org char buf[16]; 2110a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org snprintf(buf, sizeof(buf), "%d", num_base_files); 2111a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org fprintf(stderr, 2112a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org "BM_LogAndApply/%-6s %8d iters : %9u us (%7.0f us / iter)\n", 2113a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org buf, iters, us, ((float)us) / iters); 2114a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org} 2115a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org 211645b9940be332834440bd5299419f396e38085ebehans@chromium.org} // namespace leveldb 2117179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 2118179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgint main(int argc, char** argv) { 2119a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org if (argc > 1 && std::string(argv[1]) == "--benchmark") { 2120a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org leveldb::BM_LogAndApply(1000, 1); 2121a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org leveldb::BM_LogAndApply(1000, 100); 2122a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org leveldb::BM_LogAndApply(1000, 10000); 2123a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org leveldb::BM_LogAndApply(100, 100000); 2124a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org return 0; 2125a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org } 2126a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org 2127179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return leveldb::test::RunAllTests(); 2128179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 2129