├── deps └── leveldb │ ├── .gitignore │ ├── AUTHORS │ ├── TODO │ ├── port │ ├── README │ ├── port.h │ ├── win │ │ └── stdint.h │ ├── sha1_portable.h │ ├── sha1_test.cc │ ├── port_std.cc │ ├── port_posix.cc │ ├── port_android.cc │ ├── port_chromium.cc │ ├── port_posix.h │ ├── port_chromium.h │ ├── port_std.h │ └── port_android.h │ ├── NEWS │ ├── platform.env │ ├── util │ ├── hash.h │ ├── options.cc │ ├── histogram.h │ ├── hash.cc │ ├── mutexlock.h │ ├── crc32c.h │ ├── testharness.cc │ ├── testutil.cc │ ├── logging.h │ ├── env.cc │ ├── testutil.h │ ├── arena_test.cc │ ├── crc32c_test.cc │ ├── arena.h │ ├── logging.cc │ ├── status.cc │ ├── arena.cc │ ├── comparator.cc │ ├── random.h │ └── env_test.cc │ ├── base │ ├── base_api.h │ ├── port.h │ ├── atomicops_internals_x86_gcc.cc │ └── atomicops_internals_atomicword_compat.h │ ├── db │ ├── db_iter.h │ ├── log_format.h │ ├── builder.h │ ├── log_writer.h │ ├── version_edit_test.cc │ ├── write_batch_internal.h │ ├── table_cache.h │ ├── snapshot.h │ ├── builder.cc │ ├── memtable.h │ ├── write_batch_test.cc │ ├── table_cache.cc │ ├── filename.h │ ├── dbformat.cc │ ├── log_writer.cc │ ├── version_edit.h │ ├── filename_test.cc │ ├── log_reader.h │ ├── memtable.cc │ ├── write_batch.cc │ ├── dbformat_test.cc │ └── filename.cc │ ├── table │ ├── merger.h │ ├── block.h │ ├── two_level_iterator.h │ ├── iterator.cc │ ├── block_builder.h │ ├── iterator_wrapper.h │ ├── format.h │ └── block_builder.cc │ ├── doc │ ├── doc.css │ ├── table_format.txt │ └── log_format.txt │ ├── LICENSE │ ├── README │ └── include │ └── leveldb │ ├── write_batch.h │ ├── comparator.h │ ├── table.h │ ├── status.h │ ├── table_builder.h │ ├── slice.h │ ├── iterator.h │ └── cache.h ├── .gitignore ├── lib └── index.js ├── src ├── leveldb.cc ├── WriteBatch.h ├── helpers.h ├── Iterator.h ├── WriteBatch.cc ├── DB.h └── helpers.cc ├── package.json ├── demo ├── million.js ├── dumpdata.js ├── async.js ├── demo.js ├── million-async.js └── iterator.coffee ├── wscript └── README.markdown /deps/leveldb/.gitignore: -------------------------------------------------------------------------------- 1 | build/build_config.h 2 | *.o 3 | *.a 4 | *_test 5 | db_bench 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .svn 2 | *.o 3 | .lock-wscript 4 | deps/leveldb/*_test 5 | deps/leveldb/db_bench 6 | build 7 | demo/testdb 8 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | lib = require('../build/default/leveldb.node'); 2 | 3 | for (i in lib) { 4 | exports[i] = lib[i]; 5 | } 6 | 7 | -------------------------------------------------------------------------------- /deps/leveldb/AUTHORS: -------------------------------------------------------------------------------- 1 | # Names should be added to this file like so: 2 | # Name or Organization 3 | 4 | Google Inc. 5 | 6 | # Initial version authors: 7 | Jeffrey Dean 8 | Sanjay Ghemawat 9 | -------------------------------------------------------------------------------- /src/leveldb.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "DB.h" 4 | #include "WriteBatch.h" 5 | #include "Iterator.h" 6 | 7 | using namespace node_leveldb; 8 | 9 | extern "C" { 10 | static void init(Handle target) { 11 | DB::Init(target); 12 | WriteBatch::Init(target); 13 | Iterator::Init(target); 14 | } 15 | NODE_MODULE(leveldb, init); 16 | } 17 | -------------------------------------------------------------------------------- /deps/leveldb/TODO: -------------------------------------------------------------------------------- 1 | ss 2 | - Stats 3 | 4 | db 5 | - Maybe implement DB::BulkDeleteForRange(start_key, end_key) 6 | that would blow away files whose ranges are entirely contained 7 | within [start_key..end_key]? For Chrome, deletion of obsolete 8 | object stores, etc. can be done in the background anyway, so 9 | probably not that important. 10 | 11 | api changes: 12 | - Make it wrappable 13 | 14 | Faster Get implementation 15 | -------------------------------------------------------------------------------- /deps/leveldb/port/README: -------------------------------------------------------------------------------- 1 | This directory contains interfaces and implementations that isolate the 2 | rest of the package from platform details. 3 | 4 | Code in the rest of the package includes "port.h" from this directory. 5 | "port.h" in turn includes a platform specific "port_.h" file 6 | that provides the platform specific implementation. 7 | 8 | See port_posix.h for an example of what must be provided in a platform 9 | specific header file. 10 | 11 | -------------------------------------------------------------------------------- /deps/leveldb/NEWS: -------------------------------------------------------------------------------- 1 | Release 1.2 2011-05-16 2 | ---------------------- 3 | 4 | Fixes for larger databases (tested up to one billion 100-byte entries, 5 | i.e., ~100GB). 6 | 7 | (1) Place hard limit on number of level-0 files. This fixes errors 8 | of the form "too many open files". 9 | 10 | (2) Fixed memtable management. Before the fix, a heavy write burst 11 | could cause unbounded memory usage. 12 | 13 | A fix for a logging bug where the reader would incorrectly complain 14 | about corruption. 15 | 16 | Allow public access to WriteBatch contents so that users can easily 17 | wrap a DB. 18 | -------------------------------------------------------------------------------- /deps/leveldb/platform.env: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | mkdir -p build 4 | 5 | UNAME=`uname -s` 6 | case $UNAME in 7 | "Darwin") 8 | cat > build/build_config.h < build/build_config.h < 11 | #include 12 | 13 | namespace leveldb { 14 | 15 | extern uint32_t Hash(const char* data, size_t n, uint32_t seed); 16 | 17 | } 18 | 19 | #endif // STORAGE_LEVELDB_UTIL_HASH_H_ 20 | -------------------------------------------------------------------------------- /deps/leveldb/base/base_api.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef BASE_BASE_API_H_ 6 | #define BASE_BASE_API_H_ 7 | #pragma once 8 | 9 | #if defined(BASE_DLL) 10 | #if defined(WIN32) 11 | #if defined(BASE_IMPLEMENTATION) 12 | #define BASE_API __declspec(dllexport) 13 | #else 14 | #define BASE_API __declspec(dllimport) 15 | #endif // defined(BASE_IMPLEMENTATION) 16 | #else 17 | #define BASE_API __attribute__((visibility("default"))) 18 | #endif // defined(WIN32) 19 | #else 20 | #define BASE_API 21 | #endif 22 | 23 | #endif // BASE_BASE_API_H_ 24 | -------------------------------------------------------------------------------- /deps/leveldb/util/options.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include "leveldb/options.h" 6 | 7 | #include "leveldb/comparator.h" 8 | #include "leveldb/env.h" 9 | 10 | namespace leveldb { 11 | 12 | Options::Options() 13 | : comparator(BytewiseComparator()), 14 | create_if_missing(false), 15 | error_if_exists(false), 16 | paranoid_checks(false), 17 | env(Env::Default()), 18 | info_log(NULL), 19 | write_buffer_size(4<<20), 20 | max_open_files(1000), 21 | block_cache(NULL), 22 | block_size(4096), 23 | block_restart_interval(16), 24 | compression(kSnappyCompression) { 25 | } 26 | 27 | 28 | } 29 | -------------------------------------------------------------------------------- /deps/leveldb/db/db_iter.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_DB_DB_ITER_H_ 6 | #define STORAGE_LEVELDB_DB_DB_ITER_H_ 7 | 8 | #include 9 | #include "leveldb/db.h" 10 | #include "db/dbformat.h" 11 | 12 | namespace leveldb { 13 | 14 | // Return a new iterator that converts internal keys (yielded by 15 | // "*internal_iter") that were live at the specified "sequence" number 16 | // into appropriate user keys. 17 | extern Iterator* NewDBIterator( 18 | const std::string* dbname, 19 | Env* env, 20 | const Comparator* user_key_comparator, 21 | Iterator* internal_iter, 22 | const SequenceNumber& sequence); 23 | 24 | } 25 | 26 | #endif // STORAGE_LEVELDB_DB_DB_ITER_H_ 27 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "leveldb", 3 | "tags": ["database", "cache"], 4 | "description": "Bindings for using LevelDB through node.", 5 | "homepage": "https://github.com/my8bird/node-leveldb", 6 | "version": "0.3.5", 7 | "author": { 8 | "name": "Nathan Landis", 9 | "email": "my8bird@gmail.com"}, 10 | "main": "lib", 11 | "scripts": { 12 | "preinstall": "node-waf configure build" 13 | }, 14 | "repository" : { 15 | "type" : "git", 16 | "url" : "https://github.com/my8bird/node-leveldb.git" 17 | }, 18 | "keywords": ["database", "leveldb"], 19 | "bugs" : { "web" : "https://github.com/my8bird/node-leveldb/issues" }, 20 | "dependencies": 21 | { 22 | }, 23 | "contributors": [ 24 | "Randall Leeds (http://claimid.com/randallleeds)", 25 | "Damon Oehlman (http://www.sidelab.com/)" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /src/WriteBatch.h: -------------------------------------------------------------------------------- 1 | #ifndef WRITE_BATCH_H_ 2 | #define WRITE_BATCH_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "leveldb/write_batch.h" 9 | 10 | using namespace v8; 11 | using namespace node; 12 | 13 | namespace node_leveldb { 14 | 15 | class WriteBatch : ObjectWrap { 16 | public: 17 | WriteBatch(); 18 | virtual ~WriteBatch(); 19 | 20 | static void Init(Handle target); 21 | static Handle New(const Arguments& args); 22 | 23 | static Handle Put(const Arguments& args); 24 | static Handle Del(const Arguments& args); 25 | static Handle Clear(const Arguments& args); 26 | 27 | private: 28 | leveldb::WriteBatch wb; 29 | std::vector strings; 30 | 31 | static Persistent persistent_function_template; 32 | 33 | friend class DB; 34 | }; 35 | 36 | } // node_leveldb 37 | 38 | #endif // WRITE_BATCH_H_ 39 | -------------------------------------------------------------------------------- /deps/leveldb/port/port.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_PORT_PORT_H_ 6 | #define STORAGE_LEVELDB_PORT_PORT_H_ 7 | 8 | #include 9 | 10 | // Include the appropriate platform specific file below. If you are 11 | // porting to a new platform, see "port_example.h" for documentation 12 | // of what the new port_.h file must provide. 13 | #if defined(LEVELDB_PLATFORM_POSIX) 14 | # include "port/port_posix.h" 15 | #elif defined(LEVELDB_PLATFORM_CHROMIUM) 16 | # include "port/port_chromium.h" 17 | #elif defined(LEVELDB_PLATFORM_ANDROID) 18 | # include "port/port_android.h" 19 | #elif defined(LEVELDB_PLATFORM_STD) 20 | # include "port/port_std.h" 21 | #endif 22 | 23 | #endif // STORAGE_LEVELDB_PORT_PORT_H_ 24 | -------------------------------------------------------------------------------- /deps/leveldb/table/merger.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_TABLE_MERGER_H_ 6 | #define STORAGE_LEVELDB_TABLE_MERGER_H_ 7 | 8 | namespace leveldb { 9 | 10 | class Comparator; 11 | class Iterator; 12 | 13 | // Return an iterator that provided the union of the data in 14 | // children[0,n-1]. Takes ownership of the child iterators and 15 | // will delete them when the result iterator is deleted. 16 | // 17 | // The result does no duplicate suppression. I.e., if a particular 18 | // key is present in K child iterators, it will be yielded K times. 19 | // 20 | // REQUIRES: n >= 0 21 | extern Iterator* NewMergingIterator( 22 | const Comparator* comparator, Iterator** children, int n); 23 | 24 | } 25 | 26 | #endif // STORAGE_LEVELDB_TABLE_MERGER_H_ 27 | -------------------------------------------------------------------------------- /deps/leveldb/port/win/stdint.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | // MSVC didn't ship with this file until the 2010 version. 6 | 7 | #ifndef STORAGE_LEVELDB_PORT_WIN_STDINT_H_ 8 | #define STORAGE_LEVELDB_PORT_WIN_STDINT_H_ 9 | 10 | #if !defined(_MSC_VER) 11 | #error This file should only be included when compiling with MSVC. 12 | #endif 13 | 14 | // Define C99 equivalent types. 15 | typedef signed char int8_t; 16 | typedef signed short int16_t; 17 | typedef signed int int32_t; 18 | typedef signed long long int64_t; 19 | typedef unsigned char uint8_t; 20 | typedef unsigned short uint16_t; 21 | typedef unsigned int uint32_t; 22 | typedef unsigned long long uint64_t; 23 | 24 | #endif // STORAGE_LEVELDB_PORT_WIN_STDINT_H_ 25 | -------------------------------------------------------------------------------- /deps/leveldb/port/sha1_portable.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_PORT_SHA1_PORTABLE_H_ 6 | #define STORAGE_LEVELDB_PORT_SHA1_PORTABLE_H_ 7 | 8 | #include 9 | 10 | namespace leveldb { 11 | namespace port { 12 | 13 | // Compute the SHA1 hash value of "data[0..len-1]" and store it in 14 | // "hash_array[0..19]". hash_array must have 20 bytes of space available. 15 | // 16 | // This function is portable but may not be as fast as a version 17 | // optimized for your platform. It is provided as a default method 18 | // that can be used when porting leveldb to a new platform if no 19 | // better SHA1 hash implementation is available. 20 | void SHA1_Hash_Portable(const char* data, size_t len, char* hash_array); 21 | 22 | } 23 | } 24 | 25 | #endif // STORAGE_LEVELDB_PORT_SHA1_PORTABLE_H_ 26 | -------------------------------------------------------------------------------- /deps/leveldb/db/log_format.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | // 5 | // Log format information shared by reader and writer. 6 | // See ../doc/log_format.txt for more detail. 7 | 8 | #ifndef STORAGE_LEVELDB_DB_LOG_FORMAT_H_ 9 | #define STORAGE_LEVELDB_DB_LOG_FORMAT_H_ 10 | 11 | namespace leveldb { 12 | namespace log { 13 | 14 | enum RecordType { 15 | // Zero is reserved for preallocated files 16 | kZeroType = 0, 17 | 18 | kFullType = 1, 19 | 20 | // For fragments 21 | kFirstType = 2, 22 | kMiddleType = 3, 23 | kLastType = 4, 24 | }; 25 | static const int kMaxRecordType = kLastType; 26 | 27 | static const int kBlockSize = 32768; 28 | 29 | // Header is checksum (4 bytes), type (1 byte), length (2 bytes). 30 | static const int kHeaderSize = 4 + 1 + 2; 31 | 32 | } 33 | } 34 | 35 | #endif // STORAGE_LEVELDB_DB_LOG_FORMAT_H_ 36 | -------------------------------------------------------------------------------- /deps/leveldb/util/histogram.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_UTIL_HISTOGRAM_H_ 6 | #define STORAGE_LEVELDB_UTIL_HISTOGRAM_H_ 7 | 8 | #include 9 | 10 | namespace leveldb { 11 | 12 | class Histogram { 13 | public: 14 | Histogram() { } 15 | ~Histogram() { } 16 | 17 | void Clear(); 18 | void Add(double value); 19 | 20 | std::string ToString() const; 21 | 22 | private: 23 | double min_; 24 | double max_; 25 | double num_; 26 | double sum_; 27 | double sum_squares_; 28 | 29 | enum { kNumBuckets = 154 }; 30 | static const double kBucketLimit[kNumBuckets]; 31 | double buckets_[kNumBuckets]; 32 | 33 | double Median() const; 34 | double Percentile(double p) const; 35 | double Average() const; 36 | double StandardDeviation() const; 37 | }; 38 | 39 | } 40 | 41 | #endif // STORAGE_LEVELDB_UTIL_HISTOGRAM_H_ 42 | -------------------------------------------------------------------------------- /src/helpers.h: -------------------------------------------------------------------------------- 1 | #ifndef HELPERS_H_ 2 | #define HELPERS_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "leveldb/db.h" 9 | #include 10 | #include 11 | #include // for debugging 12 | 13 | using namespace node; 14 | using namespace v8; 15 | 16 | namespace node_leveldb { 17 | 18 | // Helper to convert vanilla JS objects into leveldb objects 19 | leveldb::Options JsToOptions(Handle val); 20 | leveldb::ReadOptions JsToReadOptions(Handle val); 21 | leveldb::WriteOptions JsToWriteOptions(Handle val); 22 | leveldb::Slice JsToSlice(Handle val, std::vector *strings); 23 | 24 | // Helper to convert a leveldb::Status instance to a V8 return value 25 | Handle processStatus(leveldb::Status status); 26 | 27 | // Helpers to work with buffers 28 | Local Bufferize(std::string value); 29 | char* BufferData(Buffer *b); 30 | size_t BufferLength(Buffer *b); 31 | char* BufferData(Handle buf_obj); 32 | size_t BufferLength(Handle buf_obj); 33 | 34 | } // node_leveldb 35 | 36 | #endif // HELPERS_H_ 37 | -------------------------------------------------------------------------------- /deps/leveldb/util/hash.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include 6 | #include "util/coding.h" 7 | #include "util/hash.h" 8 | 9 | namespace leveldb { 10 | 11 | uint32_t Hash(const char* data, size_t n, uint32_t seed) { 12 | // Similar to murmur hash 13 | const uint32_t m = 0xc6a4a793; 14 | const uint32_t r = 24; 15 | const char* limit = data + n; 16 | uint32_t h = seed ^ (n * m); 17 | 18 | // Pick up four bytes at a time 19 | while (data + 4 <= limit) { 20 | uint32_t w = DecodeFixed32(data); 21 | data += 4; 22 | h += w; 23 | h *= m; 24 | h ^= (h >> 16); 25 | } 26 | 27 | // Pick up remaining bytes 28 | switch (limit - data) { 29 | case 3: 30 | h += data[2] << 16; 31 | // fall through 32 | case 2: 33 | h += data[1] << 8; 34 | // fall through 35 | case 1: 36 | h += data[0]; 37 | h *= m; 38 | h ^= (h >> r); 39 | break; 40 | } 41 | return h; 42 | } 43 | 44 | 45 | } 46 | -------------------------------------------------------------------------------- /deps/leveldb/util/mutexlock.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_UTIL_MUTEXLOCK_H_ 6 | #define STORAGE_LEVELDB_UTIL_MUTEXLOCK_H_ 7 | 8 | #include "port/port.h" 9 | 10 | namespace leveldb { 11 | 12 | // Helper class that locks a mutex on construction and unlocks the mutex when 13 | // the destructor of the MutexLock object is invoked. 14 | // 15 | // Typical usage: 16 | // 17 | // void MyClass::MyMethod() { 18 | // MutexLock l(&mu_); // mu_ is an instance variable 19 | // ... some complex code, possibly with multiple return paths ... 20 | // } 21 | 22 | class MutexLock { 23 | public: 24 | explicit MutexLock(port::Mutex *mu) : mu_(mu) { 25 | this->mu_->Lock(); 26 | } 27 | ~MutexLock() { this->mu_->Unlock(); } 28 | 29 | private: 30 | port::Mutex *const mu_; 31 | // No copying allowed 32 | MutexLock(const MutexLock&); 33 | void operator=(const MutexLock&); 34 | }; 35 | 36 | } 37 | 38 | 39 | #endif // STORAGE_LEVELDB_UTIL_MUTEXLOCK_H_ 40 | -------------------------------------------------------------------------------- /deps/leveldb/table/block.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_TABLE_BLOCK_H_ 6 | #define STORAGE_LEVELDB_TABLE_BLOCK_H_ 7 | 8 | #include 9 | #include 10 | #include "leveldb/iterator.h" 11 | 12 | namespace leveldb { 13 | 14 | class Comparator; 15 | 16 | class Block { 17 | public: 18 | // Initialize the block with the specified contents. 19 | // Takes ownership of data[] and will delete[] it when done. 20 | Block(const char* data, size_t size); 21 | 22 | ~Block(); 23 | 24 | size_t size() const { return size_; } 25 | Iterator* NewIterator(const Comparator* comparator); 26 | 27 | private: 28 | uint32_t NumRestarts() const; 29 | 30 | const char* data_; 31 | size_t size_; 32 | uint32_t restart_offset_; // Offset in data_ of restart array 33 | 34 | // No copying allowed 35 | Block(const Block&); 36 | void operator=(const Block&); 37 | 38 | class Iter; 39 | }; 40 | 41 | } 42 | 43 | #endif // STORAGE_LEVELDB_TABLE_BLOCK_H_ 44 | -------------------------------------------------------------------------------- /demo/million.js: -------------------------------------------------------------------------------- 1 | var DB = require('../build/default/leveldb.node').DB; 2 | 3 | console.log("Creating test database"); 4 | var path = "/tmp/large.db"; 5 | var db = new DB(); 6 | db.open({create_if_missing: true}, path); 7 | 8 | console.log("Serializing and inserting 1,000,000 rows..."); 9 | var start = Date.now(); 10 | for (var i = 0; i < 1000000; i++) { 11 | db.put({}, new Buffer("row" + i), new Buffer(JSON.stringify({ 12 | index: i, 13 | name: "Tim", 14 | age: 28 15 | }))); 16 | } 17 | var delta = Date.now() - start; 18 | console.log("Completed in %d ms", delta); 19 | console.log("%s inserts per second", Math.floor(1000000000 / delta)); 20 | 21 | var data = new Buffer(4096); 22 | for (i = 0; i < 4096; i++) { 23 | data[i] = Math.floor(Math.random() * 256); 24 | } 25 | console.log("Inserting the same 4k random bytes into 100,000 rows"); 26 | start = Date.now(); 27 | for (i = 0; i < 100000; i++) { 28 | db.put({}, new Buffer("binary" + i), data); 29 | } 30 | delta = Date.now() - start; 31 | console.log("Completed in %d ms", delta); 32 | console.log("%s inserts per second", Math.floor(100000000 / delta)); 33 | 34 | console.log("Closing and destroying database"); 35 | db.close(); 36 | DB.destroyDB(path, {}); 37 | 38 | -------------------------------------------------------------------------------- /deps/leveldb/port/sha1_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include "port/port.h" 6 | #include "util/testharness.h" 7 | 8 | namespace leveldb { 9 | namespace port { 10 | 11 | class SHA1 { }; 12 | 13 | static std::string TestSHA1(const char* data, size_t len) { 14 | char hash_val[20]; 15 | SHA1_Hash(data, len, hash_val); 16 | char buf[41]; 17 | for (int i = 0; i < 20; i++) { 18 | snprintf(buf + i * 2, 41 - i * 2, 19 | "%02x", 20 | static_cast(static_cast( 21 | hash_val[i]))); 22 | } 23 | return std::string(buf, 40); 24 | } 25 | 26 | TEST(SHA1, Simple) { 27 | ASSERT_EQ("da39a3ee5e6b4b0d3255bfef95601890afd80709", TestSHA1("", 0)); 28 | ASSERT_EQ("aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d", TestSHA1("hello", 5)); 29 | std::string x(10000, 'x'); 30 | ASSERT_EQ("f8c5cde791c5056cf515881e701c8a9ecb439a75", 31 | TestSHA1(x.data(), x.size())); 32 | } 33 | 34 | } 35 | } 36 | 37 | int main(int argc, char** argv) { 38 | return leveldb::test::RunAllTests(); 39 | } 40 | -------------------------------------------------------------------------------- /demo/dumpdata.js: -------------------------------------------------------------------------------- 1 | var leveldb = require('../build/default/leveldb.node'), 2 | DB = leveldb.DB, 3 | Iterator = leveldb.Iterator; 4 | 5 | var path = "/tmp/large.db"; 6 | 7 | var index = 0; 8 | var in_flight = 0; 9 | var found = 0; 10 | var not_found = 0; 11 | 12 | var db = new DB(); 13 | db.open(path, function(err) { 14 | if (err) throw err; 15 | 16 | setInterval(function() { 17 | console.log('Index: ' + index + ' In flight: ' + in_flight + ' Found: ' + found + ' Not found: ' + not_found); 18 | refresh(); 19 | }, 100); 20 | 21 | refresh(); 22 | }); 23 | 24 | function refresh() { 25 | while (in_flight < 10000) { 26 | var key = "row" + index; 27 | 28 | db.get(key, (function(index) { return function(err, value) { 29 | in_flight -= 1; 30 | if (value) { 31 | var obj = JSON.parse(value); 32 | if (obj.index != index) { 33 | console.log('key: ' + key + ' = ' + value); 34 | } 35 | found += 1; 36 | } 37 | else { 38 | not_found += 1; 39 | } 40 | }})(index)); 41 | 42 | in_flight += 1; 43 | index += 1; 44 | } 45 | } 46 | 47 | -------------------------------------------------------------------------------- /deps/leveldb/db/builder.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_DB_BUILDER_H_ 6 | #define STORAGE_LEVELDB_DB_BUILDER_H_ 7 | 8 | #include "leveldb/status.h" 9 | 10 | namespace leveldb { 11 | 12 | struct Options; 13 | struct FileMetaData; 14 | 15 | class Env; 16 | class Iterator; 17 | class TableCache; 18 | class VersionEdit; 19 | 20 | // Build a Table file from the contents of *iter. The generated file 21 | // will be named according to meta->number. On success, the rest of 22 | // *meta will be filled with metadata about the generated table, and 23 | // the file information will be added to *edit. If no data is present 24 | // in *iter, meta->file_size will be set to zero, and no Table file 25 | // will be produced. 26 | extern Status BuildTable(const std::string& dbname, 27 | Env* env, 28 | const Options& options, 29 | TableCache* table_cache, 30 | Iterator* iter, 31 | FileMetaData* meta, 32 | VersionEdit* edit); 33 | 34 | } 35 | 36 | #endif // STORAGE_LEVELDB_DB_BUILDER_H_ 37 | -------------------------------------------------------------------------------- /deps/leveldb/table/two_level_iterator.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_TABLE_TWO_LEVEL_ITERATOR_H_ 6 | #define STORAGE_LEVELDB_TABLE_TWO_LEVEL_ITERATOR_H_ 7 | 8 | #include "leveldb/iterator.h" 9 | 10 | namespace leveldb { 11 | 12 | struct ReadOptions; 13 | 14 | // Return a new two level iterator. A two-level iterator contains an 15 | // index iterator whose values point to a sequence of blocks where 16 | // each block is itself a sequence of key,value pairs. The returned 17 | // two-level iterator yields the concatenation of all key/value pairs 18 | // in the sequence of blocks. Takes ownership of "index_iter" and 19 | // will delete it when no longer needed. 20 | // 21 | // Uses a supplied function to convert an index_iter value into 22 | // an iterator over the contents of the corresponding block. 23 | extern Iterator* NewTwoLevelIterator( 24 | Iterator* index_iter, 25 | Iterator* (*block_function)( 26 | void* arg, 27 | const ReadOptions& options, 28 | const Slice& index_value), 29 | void* arg, 30 | const ReadOptions& options); 31 | 32 | } 33 | 34 | #endif // STORAGE_LEVELDB_TABLE_TWO_LEVEL_ITERATOR_H_ 35 | -------------------------------------------------------------------------------- /demo/async.js: -------------------------------------------------------------------------------- 1 | var leveldb = require('../build/default/leveldb.node'), 2 | DB = leveldb.DB, 3 | Iterator = leveldb.Iterator, 4 | WriteBatch = leveldb.WriteBatch; 5 | 6 | var path = __dirname + "/testdb"; 7 | 8 | var db = new DB(); 9 | 10 | // Opening 11 | console.log("Opening..."); 12 | db.open(path, {create_if_missing: true, paranoid_checks: true}, function(err) { 13 | if (err) throw err; 14 | console.log("ok"); 15 | 16 | // Putting 17 | console.log("\nPutting..."); 18 | var key = "Hello"; 19 | var value = "World"; 20 | db.put(key, value, function(err) { 21 | if (err) throw err; 22 | console.log("ok"); 23 | 24 | // Getting 25 | console.log("\nGetting..."); 26 | db.get(key, function(err, val) { 27 | if (err) throw err; 28 | if (val != value) throw "Expected: " + value + ", got: " + val; 29 | console.log("ok"); 30 | 31 | // Deleting 32 | console.log("\nDeleting..."); 33 | db.del(key, function(err) { 34 | if (err) throw err; 35 | console.log("ok"); 36 | 37 | // Closing 38 | console.log("\nClosing...") 39 | db.close(function(err) { 40 | if (err) throw err; 41 | console.log('ok'); 42 | }); 43 | }); 44 | }); 45 | }); 46 | }); 47 | 48 | -------------------------------------------------------------------------------- /deps/leveldb/db/log_writer.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_DB_LOG_WRITER_H_ 6 | #define STORAGE_LEVELDB_DB_LOG_WRITER_H_ 7 | 8 | #include 9 | #include "db/log_format.h" 10 | #include "leveldb/slice.h" 11 | #include "leveldb/status.h" 12 | 13 | namespace leveldb { 14 | 15 | class WritableFile; 16 | 17 | namespace log { 18 | 19 | class Writer { 20 | public: 21 | // Create a writer that will append data to "*dest". 22 | // "*dest" must be initially empty. 23 | // "*dest" must remain live while this Writer is in use. 24 | explicit Writer(WritableFile* dest); 25 | ~Writer(); 26 | 27 | Status AddRecord(const Slice& slice); 28 | 29 | private: 30 | WritableFile* dest_; 31 | int block_offset_; // Current offset in block 32 | 33 | // crc32c values for all supported record types. These are 34 | // pre-computed to reduce the overhead of computing the crc of the 35 | // record type stored in the header. 36 | uint32_t type_crc_[kMaxRecordType + 1]; 37 | 38 | Status EmitPhysicalRecord(RecordType type, const char* ptr, size_t length); 39 | 40 | // No copying allowed 41 | Writer(const Writer&); 42 | void operator=(const Writer&); 43 | }; 44 | 45 | } 46 | } 47 | 48 | #endif // STORAGE_LEVELDB_DB_LOG_WRITER_H_ 49 | -------------------------------------------------------------------------------- /deps/leveldb/port/port_std.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include "port/port_std.h" 6 | 7 | #include 8 | #include 9 | #include 10 | #include "util/logging.h" 11 | 12 | namespace leveldb { 13 | namespace port { 14 | 15 | static void PthreadCall(const char* label, int result) { 16 | if (result != 0) { 17 | fprintf(stderr, "pthread %s: %s\n", label, strerror(result)); 18 | abort(); 19 | } 20 | } 21 | 22 | Mutex::Mutex() { PthreadCall("init mutex", pthread_mutex_init(&mu_, NULL)); } 23 | 24 | Mutex::~Mutex() { PthreadCall("destroy mutex", pthread_mutex_destroy(&mu_)); } 25 | 26 | void Mutex::Lock() { PthreadCall("lock", pthread_mutex_lock(&mu_)); } 27 | 28 | void Mutex::Unlock() { PthreadCall("unlock", pthread_mutex_unlock(&mu_)); } 29 | 30 | CondVar::CondVar(Mutex* mu) 31 | : mu_(mu) { 32 | PthreadCall("init cv", pthread_cond_init(&cv_, NULL)); 33 | } 34 | 35 | CondVar::~CondVar() { PthreadCall("destroy cv", pthread_cond_destroy(&cv_)); } 36 | 37 | void CondVar::Wait() { 38 | PthreadCall("wait", pthread_cond_wait(&cv_, &mu_->mu_)); 39 | } 40 | 41 | void CondVar::Signal() { 42 | PthreadCall("signal", pthread_cond_signal(&cv_)); 43 | } 44 | 45 | void CondVar::SignalAll() { 46 | PthreadCall("broadcast", pthread_cond_broadcast(&cv_)); 47 | } 48 | 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /demo/demo.js: -------------------------------------------------------------------------------- 1 | var leveldb = require('../build/default/leveldb.node'), 2 | DB = leveldb.DB, 3 | Iterator = leveldb.Iterator, 4 | WriteBatch = leveldb.WriteBatch; 5 | 6 | var path = __dirname + "/testdb"; 7 | 8 | var db = new DB(); 9 | 10 | // Opening 11 | console.log("Opening..."); 12 | var status = db.open({create_if_missing: true, paranoid_checks: true}, path); 13 | console.log(status); 14 | 15 | // Putting 16 | console.log("\nPutting..."); 17 | var key = new Buffer("Hello"); 18 | var value = new Buffer("World"); 19 | var status = db.put({}, key, value); 20 | console.log(status); 21 | 22 | // Getting 23 | console.log("\nGetting..."); 24 | if(value.toString() == db.get({}, key).toString()) { 25 | console.log("OK"); 26 | } else { 27 | console.log("FAIL"); 28 | } 29 | 30 | // Bulk writing 31 | console.log("\nBulk writing..."); 32 | var wb = new WriteBatch(); 33 | wb.put(new Buffer('foo'), new Buffer('bar')); 34 | wb.put(new Buffer('booz'), new Buffer('baz')); 35 | var status = db.write({}, wb); 36 | console.log("Bulk writing: putting: " + status); 37 | 38 | if (db.get({}, new Buffer('booz')).toString() == 'baz' && 39 | db.get({}, new Buffer('foo')).toString() == 'bar') { 40 | var status = "OK"; 41 | } else { 42 | var status = "FAIL"; 43 | } 44 | console.log("Bulk writing: getting: " + status); 45 | 46 | // Deleting 47 | console.log("\nDeleting..."); 48 | var status = db.del({}, key); 49 | console.log(status); 50 | 51 | // Closing 52 | console.log("\nClosing..."); 53 | db.close(); 54 | console.log("OK"); -------------------------------------------------------------------------------- /deps/leveldb/port/port_posix.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include "port/port_posix.h" 6 | 7 | #include 8 | #include 9 | #include 10 | #include "util/logging.h" 11 | 12 | namespace leveldb { 13 | namespace port { 14 | 15 | static void PthreadCall(const char* label, int result) { 16 | if (result != 0) { 17 | fprintf(stderr, "pthread %s: %s\n", label, strerror(result)); 18 | abort(); 19 | } 20 | } 21 | 22 | Mutex::Mutex() { PthreadCall("init mutex", pthread_mutex_init(&mu_, NULL)); } 23 | 24 | Mutex::~Mutex() { PthreadCall("destroy mutex", pthread_mutex_destroy(&mu_)); } 25 | 26 | void Mutex::Lock() { PthreadCall("lock", pthread_mutex_lock(&mu_)); } 27 | 28 | void Mutex::Unlock() { PthreadCall("unlock", pthread_mutex_unlock(&mu_)); } 29 | 30 | CondVar::CondVar(Mutex* mu) 31 | : mu_(mu) { 32 | PthreadCall("init cv", pthread_cond_init(&cv_, NULL)); 33 | } 34 | 35 | CondVar::~CondVar() { PthreadCall("destroy cv", pthread_cond_destroy(&cv_)); } 36 | 37 | void CondVar::Wait() { 38 | PthreadCall("wait", pthread_cond_wait(&cv_, &mu_->mu_)); 39 | } 40 | 41 | void CondVar::Signal() { 42 | PthreadCall("signal", pthread_cond_signal(&cv_)); 43 | } 44 | 45 | void CondVar::SignalAll() { 46 | PthreadCall("broadcast", pthread_cond_broadcast(&cv_)); 47 | } 48 | 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /deps/leveldb/db/version_edit_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include "db/version_edit.h" 6 | #include "util/testharness.h" 7 | 8 | namespace leveldb { 9 | 10 | static void TestEncodeDecode(const VersionEdit& edit) { 11 | std::string encoded, encoded2; 12 | edit.EncodeTo(&encoded); 13 | VersionEdit parsed; 14 | Status s = parsed.DecodeFrom(encoded); 15 | ASSERT_TRUE(s.ok()) << s.ToString(); 16 | parsed.EncodeTo(&encoded2); 17 | ASSERT_EQ(encoded, encoded2); 18 | } 19 | 20 | class VersionEditTest { }; 21 | 22 | TEST(VersionEditTest, EncodeDecode) { 23 | static const uint64_t kBig = 1ull << 50; 24 | 25 | VersionEdit edit; 26 | for (int i = 0; i < 4; i++) { 27 | TestEncodeDecode(edit); 28 | edit.AddFile(3, kBig + 300 + i, kBig + 400 + i, 29 | InternalKey("foo", kBig + 500 + i, kTypeValue), 30 | InternalKey("zoo", kBig + 600 + i, kTypeDeletion)); 31 | edit.DeleteFile(4, kBig + 700 + i); 32 | edit.SetCompactPointer(i, InternalKey("x", kBig + 900 + i, kTypeValue)); 33 | } 34 | 35 | edit.SetComparatorName("foo"); 36 | edit.SetLogNumber(kBig + 100); 37 | edit.SetNextFile(kBig + 200); 38 | edit.SetLastSequence(kBig + 1000); 39 | TestEncodeDecode(edit); 40 | } 41 | 42 | } 43 | 44 | int main(int argc, char** argv) { 45 | return leveldb::test::RunAllTests(); 46 | } 47 | -------------------------------------------------------------------------------- /deps/leveldb/doc/doc.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin-left: 0.5in; 3 | margin-right: 0.5in; 4 | background: white; 5 | color: black; 6 | } 7 | 8 | h1 { 9 | margin-left: -0.2in; 10 | font-size: 14pt; 11 | } 12 | h2 { 13 | margin-left: -0in; 14 | font-size: 12pt; 15 | } 16 | h3 { 17 | margin-left: -0in; 18 | } 19 | h4 { 20 | margin-left: -0in; 21 | } 22 | hr { 23 | margin-left: -0in; 24 | } 25 | 26 | /* Definition lists: definition term bold */ 27 | dt { 28 | font-weight: bold; 29 | } 30 | 31 | address { 32 | text-align: center; 33 | } 34 | code,samp,var { 35 | color: blue; 36 | } 37 | kbd { 38 | color: #600000; 39 | } 40 | div.note p { 41 | float: right; 42 | width: 3in; 43 | margin-right: 0%; 44 | padding: 1px; 45 | border: 2px solid #6060a0; 46 | background-color: #fffff0; 47 | } 48 | 49 | ul { 50 | margin-top: -0em; 51 | margin-bottom: -0em; 52 | } 53 | 54 | ol { 55 | margin-top: -0em; 56 | margin-bottom: -0em; 57 | } 58 | 59 | UL.nobullets { 60 | list-style-type: none; 61 | list-style-image: none; 62 | margin-left: -1em; 63 | } 64 | 65 | p { 66 | margin: 1em 0 1em 0; 67 | padding: 0 0 0 0; 68 | } 69 | 70 | pre { 71 | line-height: 1.3em; 72 | padding: 0.4em 0 0.8em 0; 73 | margin: 0 0 0 0; 74 | border: 0 0 0 0; 75 | color: blue; 76 | } 77 | 78 | .datatable { 79 | margin-left: auto; 80 | margin-right: auto; 81 | margin-top: 2em; 82 | margin-bottom: 2em; 83 | border: 1px solid; 84 | } 85 | 86 | .datatable td,th { 87 | padding: 0 0.5em 0 0.5em; 88 | text-align: right; 89 | } 90 | -------------------------------------------------------------------------------- /demo/million-async.js: -------------------------------------------------------------------------------- 1 | var leveldb = require('../build/default/leveldb.node'), 2 | DB = leveldb.DB, 3 | WriteBatch = leveldb.WriteBatch; 4 | 5 | console.log("Creating test database"); 6 | var path = "/tmp/large.db"; 7 | var db = new DB(); 8 | 9 | var batchSize = 100; 10 | var totalSize = 1000000; 11 | 12 | db.open(path, {create_if_missing: true}, function() { 13 | 14 | console.log("Serializing and inserting 1,000,000 rows..."); 15 | var start = Date.now(); 16 | 17 | function doBatch(i, cb) { 18 | if (i % 10000 == 0) 19 | console.log("i = " + i); 20 | 21 | var wb = new WriteBatch(); 22 | 23 | for (var j = 0; j < batchSize; j += 1) { 24 | var key = "row" + i; 25 | var value = JSON.stringify({ 26 | index: i, 27 | name: "Tim", 28 | age: 28 29 | }); 30 | wb.put(key, value); 31 | i += 1; 32 | } 33 | 34 | db.write(wb, function() { 35 | if (i < totalSize) 36 | doBatch(i, cb); 37 | else 38 | cb(); 39 | }); 40 | } 41 | 42 | doBatch(0, function() { 43 | var delta = Date.now() - start; 44 | console.log("Completed in %d ms", delta); 45 | console.log("%s inserts per second", Math.floor(totalSize * 1000 / delta)); 46 | 47 | console.log("\nClosing..."); 48 | db.close(function() { 49 | console.log("Done"); 50 | }); 51 | }); 52 | }); 53 | -------------------------------------------------------------------------------- /deps/leveldb/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /deps/leveldb/util/crc32c.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_UTIL_CRC32C_H_ 6 | #define STORAGE_LEVELDB_UTIL_CRC32C_H_ 7 | 8 | #include 9 | #include 10 | 11 | namespace leveldb { 12 | namespace crc32c { 13 | 14 | // Return the crc32c of concat(A, data[0,n-1]) where init_crc is the 15 | // crc32c of some string A. Extend() is often used to maintain the 16 | // crc32c of a stream of data. 17 | extern uint32_t Extend(uint32_t init_crc, const char* data, size_t n); 18 | 19 | // Return the crc32c of data[0,n-1] 20 | inline uint32_t Value(const char* data, size_t n) { 21 | return Extend(0, data, n); 22 | } 23 | 24 | static const uint32_t kMaskDelta = 0xa282ead8ul; 25 | 26 | // Return a masked representation of crc. 27 | // 28 | // Motivation: it is problematic to compute the CRC of a string that 29 | // contains embedded CRCs. Therefore we recommend that CRCs stored 30 | // somewhere (e.g., in files) should be masked before being stored. 31 | inline uint32_t Mask(uint32_t crc) { 32 | // Rotate right by 15 bits and add a constant. 33 | return ((crc >> 15) | (crc << 17)) + kMaskDelta; 34 | } 35 | 36 | // Return the crc whose masked representation is masked_crc. 37 | inline uint32_t Unmask(uint32_t masked_crc) { 38 | uint32_t rot = masked_crc - kMaskDelta; 39 | return ((rot >> 17) | (rot << 15)); 40 | } 41 | 42 | } 43 | } 44 | 45 | #endif // STORAGE_LEVELDB_UTIL_CRC32C_H_ 46 | -------------------------------------------------------------------------------- /deps/leveldb/db/write_batch_internal.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_DB_WRITE_BATCH_INTERNAL_H_ 6 | #define STORAGE_LEVELDB_DB_WRITE_BATCH_INTERNAL_H_ 7 | 8 | #include "leveldb/write_batch.h" 9 | 10 | namespace leveldb { 11 | 12 | // WriteBatchInternal provides static methods for manipulating a 13 | // WriteBatch that we don't want in the public WriteBatch interface. 14 | class WriteBatchInternal { 15 | public: 16 | // Return the number of entries in the batch. 17 | static int Count(const WriteBatch* batch); 18 | 19 | // Set the count for the number of entries in the batch. 20 | static void SetCount(WriteBatch* batch, int n); 21 | 22 | // Return the seqeunce number for the start of this batch. 23 | static SequenceNumber Sequence(const WriteBatch* batch); 24 | 25 | // Store the specified number as the seqeunce number for the start of 26 | // this batch. 27 | static void SetSequence(WriteBatch* batch, SequenceNumber seq); 28 | 29 | static Slice Contents(const WriteBatch* batch) { 30 | return Slice(batch->rep_); 31 | } 32 | 33 | static size_t ByteSize(const WriteBatch* batch) { 34 | return batch->rep_.size(); 35 | } 36 | 37 | static void SetContents(WriteBatch* batch, const Slice& contents); 38 | 39 | static Status InsertInto(const WriteBatch* batch, MemTable* memtable); 40 | }; 41 | 42 | } 43 | 44 | 45 | #endif // STORAGE_LEVELDB_DB_WRITE_BATCH_INTERNAL_H_ 46 | -------------------------------------------------------------------------------- /deps/leveldb/util/testharness.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include "util/testharness.h" 6 | 7 | #include 8 | #include 9 | 10 | namespace leveldb { 11 | namespace test { 12 | 13 | namespace { 14 | struct Test { 15 | const char* base; 16 | const char* name; 17 | void (*func)(); 18 | }; 19 | std::vector* tests; 20 | } 21 | 22 | bool RegisterTest(const char* base, const char* name, void (*func)()) { 23 | if (tests == NULL) { 24 | tests = new std::vector; 25 | } 26 | Test t; 27 | t.base = base; 28 | t.name = name; 29 | t.func = func; 30 | tests->push_back(t); 31 | return true; 32 | } 33 | 34 | int RunAllTests() { 35 | int num = 0; 36 | if (tests != NULL) { 37 | for (int i = 0; i < tests->size(); i++) { 38 | const Test& t = (*tests)[i]; 39 | fprintf(stderr, "==== Test %s.%s\n", t.base, t.name); 40 | (*t.func)(); 41 | ++num; 42 | } 43 | } 44 | fprintf(stderr, "==== PASSED %d tests\n", num); 45 | return 0; 46 | } 47 | 48 | std::string TmpDir() { 49 | std::string dir; 50 | Status s = Env::Default()->GetTestDirectory(&dir); 51 | ASSERT_TRUE(s.ok()) << s.ToString(); 52 | return dir; 53 | } 54 | 55 | int RandomSeed() { 56 | const char* env = getenv("TEST_RANDOM_SEED"); 57 | int result = (env != NULL ? atoi(env) : 301); 58 | if (result <= 0) { 59 | result = 301; 60 | } 61 | return result; 62 | } 63 | 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /deps/leveldb/util/testutil.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include "util/testutil.h" 6 | 7 | #include "util/random.h" 8 | 9 | namespace leveldb { 10 | namespace test { 11 | 12 | Slice RandomString(Random* rnd, int len, std::string* dst) { 13 | dst->resize(len); 14 | for (int i = 0; i < len; i++) { 15 | (*dst)[i] = static_cast(' ' + rnd->Uniform(95)); // ' ' .. '~' 16 | } 17 | return Slice(*dst); 18 | } 19 | 20 | std::string RandomKey(Random* rnd, int len) { 21 | // Make sure to generate a wide variety of characters so we 22 | // test the boundary conditions for short-key optimizations. 23 | static const char kTestChars[] = { 24 | '\0', '\1', 'a', 'b', 'c', 'd', 'e', '\xfd', '\xfe', '\xff' 25 | }; 26 | std::string result; 27 | for (int i = 0; i < len; i++) { 28 | result += kTestChars[rnd->Uniform(sizeof(kTestChars))]; 29 | } 30 | return result; 31 | } 32 | 33 | 34 | extern Slice CompressibleString(Random* rnd, double compressed_fraction, 35 | int len, std::string* dst) { 36 | int raw = static_cast(len * compressed_fraction); 37 | if (raw < 1) raw = 1; 38 | std::string raw_data; 39 | RandomString(rnd, raw, &raw_data); 40 | 41 | // Duplicate the random data until we have filled "len" bytes 42 | dst->clear(); 43 | while (dst->size() < len) { 44 | dst->append(raw_data); 45 | } 46 | dst->resize(len); 47 | return Slice(*dst); 48 | } 49 | 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /deps/leveldb/db/table_cache.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | // 5 | // Thread-safe (provides internal synchronization) 6 | 7 | #ifndef STORAGE_LEVELDB_DB_TABLE_CACHE_H_ 8 | #define STORAGE_LEVELDB_DB_TABLE_CACHE_H_ 9 | 10 | #include 11 | #include 12 | #include "db/dbformat.h" 13 | #include "leveldb/cache.h" 14 | #include "leveldb/table.h" 15 | #include "port/port.h" 16 | 17 | namespace leveldb { 18 | 19 | class Env; 20 | 21 | class TableCache { 22 | public: 23 | TableCache(const std::string& dbname, const Options* options, int entries); 24 | ~TableCache(); 25 | 26 | // Return an iterator for the specified file number (the corresponding 27 | // file length must be exactly "file_size" bytes). If "tableptr" is 28 | // non-NULL, also sets "*tableptr" to point to the Table object 29 | // underlying the returned iterator, or NULL if no Table object underlies 30 | // the returned iterator. The returned "*tableptr" object is owned by 31 | // the cache and should not be deleted, and is valid for as long as the 32 | // returned iterator is live. 33 | Iterator* NewIterator(const ReadOptions& options, 34 | uint64_t file_number, 35 | uint64_t file_size, 36 | Table** tableptr = NULL); 37 | 38 | // Evict any entry for the specified file number 39 | void Evict(uint64_t file_number); 40 | 41 | private: 42 | Env* const env_; 43 | const std::string dbname_; 44 | const Options* options_; 45 | Cache* cache_; 46 | }; 47 | 48 | } 49 | 50 | #endif // STORAGE_LEVELDB_DB_TABLE_CACHE_H_ 51 | -------------------------------------------------------------------------------- /deps/leveldb/util/logging.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | // 5 | // Must not be included from any .h files to avoid polluting the namespace 6 | // with macros. 7 | 8 | #ifndef STORAGE_LEVELDB_UTIL_LOGGING_H_ 9 | #define STORAGE_LEVELDB_UTIL_LOGGING_H_ 10 | 11 | #include 12 | #include 13 | #include 14 | #include "port/port.h" 15 | 16 | namespace leveldb { 17 | 18 | class Slice; 19 | class WritableFile; 20 | 21 | // Append a human-readable printout of "num" to *str 22 | extern void AppendNumberTo(std::string* str, uint64_t num); 23 | 24 | // Append a human-readable printout of "value" to *str. 25 | // Escapes any non-printable characters found in "value". 26 | extern void AppendEscapedStringTo(std::string* str, const Slice& value); 27 | 28 | // Return a human-readable printout of "num" 29 | extern std::string NumberToString(uint64_t num); 30 | 31 | // Return a human-readable version of "value". 32 | // Escapes any non-printable characters found in "value". 33 | extern std::string EscapeString(const Slice& value); 34 | 35 | // If *in starts with "c", advances *in past the first character and 36 | // returns true. Otherwise, returns false. 37 | extern bool ConsumeChar(Slice* in, char c); 38 | 39 | // Parse a human-readable number from "*in" into *value. On success, 40 | // advances "*in" past the consumed number and sets "*val" to the 41 | // numeric value. Otherwise, returns false and leaves *in in an 42 | // unspecified state. 43 | extern bool ConsumeDecimalNumber(Slice* in, uint64_t* val); 44 | 45 | } 46 | 47 | #endif // STORAGE_LEVELDB_UTIL_LOGGING_H_ 48 | -------------------------------------------------------------------------------- /deps/leveldb/port/port_android.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include "port/port_android.h" 6 | 7 | #include 8 | 9 | extern "C" { 10 | size_t fread_unlocked(void *a, size_t b, size_t c, FILE *d) { 11 | return fread(a, b, c, d); 12 | } 13 | 14 | size_t fwrite_unlocked(const void *a, size_t b, size_t c, FILE *d) { 15 | return fwrite(a, b, c, d); 16 | } 17 | 18 | int fflush_unlocked(FILE *f) { 19 | return fflush(f); 20 | } 21 | 22 | int fdatasync(int fd) { 23 | return fsync(fd); 24 | } 25 | } 26 | 27 | namespace leveldb { 28 | namespace port { 29 | 30 | static void PthreadCall(const char* label, int result) { 31 | if (result != 0) { 32 | fprintf(stderr, "pthread %s: %s\n", label, strerror(result)); 33 | abort(); 34 | } 35 | } 36 | 37 | Mutex::Mutex() { PthreadCall("init mutex", pthread_mutex_init(&mu_, NULL)); } 38 | Mutex::~Mutex() { PthreadCall("destroy mutex", pthread_mutex_destroy(&mu_)); } 39 | void Mutex::Lock() { PthreadCall("lock", pthread_mutex_lock(&mu_)); } 40 | void Mutex::Unlock() { PthreadCall("unlock", pthread_mutex_unlock(&mu_)); } 41 | 42 | CondVar::CondVar(Mutex* mu) 43 | : mu_(mu) { 44 | PthreadCall("init cv", pthread_cond_init(&cv_, NULL)); 45 | } 46 | 47 | CondVar::~CondVar() { 48 | PthreadCall("destroy cv", pthread_cond_destroy(&cv_)); 49 | } 50 | 51 | void CondVar::Wait() { 52 | PthreadCall("wait", pthread_cond_wait(&cv_, &mu_->mu_)); 53 | } 54 | 55 | void CondVar::Signal(){ 56 | PthreadCall("signal", pthread_cond_signal(&cv_)); 57 | } 58 | 59 | void CondVar::SignalAll() { 60 | PthreadCall("broadcast", pthread_cond_broadcast(&cv_)); 61 | } 62 | 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /deps/leveldb/port/port_chromium.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include "port/port_chromium.h" 6 | 7 | #include "util/logging.h" 8 | 9 | #if defined(USE_SNAPPY) 10 | # include "third_party/snappy/src/snappy.h" 11 | #endif 12 | 13 | namespace leveldb { 14 | namespace port { 15 | 16 | Mutex::Mutex() { 17 | } 18 | 19 | Mutex::~Mutex() { 20 | } 21 | 22 | void Mutex::Lock() { 23 | mu_.Acquire(); 24 | } 25 | 26 | void Mutex::Unlock() { 27 | mu_.Release(); 28 | } 29 | 30 | void Mutex::AssertHeld() { 31 | mu_.AssertAcquired(); 32 | } 33 | 34 | CondVar::CondVar(Mutex* mu) 35 | : cv_(&mu->mu_) { 36 | } 37 | 38 | CondVar::~CondVar() { } 39 | 40 | void CondVar::Wait() { 41 | cv_.Wait(); 42 | } 43 | 44 | void CondVar::Signal(){ 45 | cv_.Signal(); 46 | } 47 | 48 | void CondVar::SignalAll() { 49 | cv_.Broadcast(); 50 | } 51 | 52 | bool Snappy_Compress(const char* input, size_t input_length, 53 | std::string* output) { 54 | #if defined(USE_SNAPPY) 55 | output->resize(snappy::MaxCompressedLength(input_length)); 56 | size_t outlen; 57 | snappy::RawCompress(input, input_length, &(*output)[0], &outlen); 58 | output->resize(outlen); 59 | return true; 60 | #else 61 | return false; 62 | #endif 63 | } 64 | 65 | bool Snappy_Uncompress(const char* input_data, size_t input_length, 66 | std::string* output) { 67 | #if defined(USE_SNAPPY) 68 | size_t ulength; 69 | if (!snappy::GetUncompressedLength(input_data, input_length, &ulength)) { 70 | return false; 71 | } 72 | output->resize(ulength); 73 | return snappy::RawUncompress(input_data, input_length, &(*output)[0]); 74 | #else 75 | return false; 76 | #endif 77 | } 78 | 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /deps/leveldb/README: -------------------------------------------------------------------------------- 1 | leveldb: A key-value store 2 | Authors: Sanjay Ghemawat (sanjay@google.com) and Jeff Dean (jeff@google.com) 3 | 4 | The code under this directory implements a system for maintaining a 5 | persistent key/value store. 6 | 7 | See doc/index.html for more explanation. 8 | See doc/impl.html for a brief overview of the implementation. 9 | 10 | The public interface is in include/*.h. Callers should not include or 11 | rely on the details of any other header files in this package. Those 12 | internal APIs may be changed without warning. 13 | 14 | Guide to header files: 15 | 16 | include/db.h 17 | Main interface to the DB: Start here 18 | 19 | include/options.h 20 | Control over the behavior of an entire database, and also 21 | control over the behavior of individual reads and writes. 22 | 23 | include/comparator.h 24 | Abstraction for user-specified comparison function. If you want 25 | just bytewise comparison of keys, you can use the default comparator, 26 | but clients can write their own comparator implementations if they 27 | want custom ordering (e.g. to handle different character 28 | encodings, etc.) 29 | 30 | include/iterator.h 31 | Interface for iterating over data. You can get an iterator 32 | from a DB object. 33 | 34 | include/write_batch.h 35 | Interface for atomically applying multiple updates to a database. 36 | 37 | include/slice.h 38 | A simple module for maintaining a pointer and a length into some 39 | other byte array. 40 | 41 | include/status.h 42 | Status is returned from many of the public interfaces and is used 43 | to report success and various kinds of errors. 44 | 45 | include/env.h 46 | Abstraction of the OS environment. A posix implementation of 47 | this interface is in util/env_posix.cc 48 | 49 | include/table.h 50 | include/table_builder.h 51 | Lower-level modules that most clients probably won't use directly 52 | -------------------------------------------------------------------------------- /deps/leveldb/util/env.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include "leveldb/env.h" 6 | 7 | namespace leveldb { 8 | 9 | Env::~Env() { 10 | } 11 | 12 | SequentialFile::~SequentialFile() { 13 | } 14 | 15 | RandomAccessFile::~RandomAccessFile() { 16 | } 17 | 18 | WritableFile::~WritableFile() { 19 | } 20 | 21 | FileLock::~FileLock() { 22 | } 23 | 24 | void Log(Env* env, WritableFile* info_log, const char* format, ...) { 25 | va_list ap; 26 | va_start(ap, format); 27 | env->Logv(info_log, format, ap); 28 | va_end(ap); 29 | } 30 | 31 | Status WriteStringToFile(Env* env, const Slice& data, 32 | const std::string& fname) { 33 | WritableFile* file; 34 | Status s = env->NewWritableFile(fname, &file); 35 | if (!s.ok()) { 36 | return s; 37 | } 38 | s = file->Append(data); 39 | if (s.ok()) { 40 | s = file->Close(); 41 | } 42 | delete file; // Will auto-close if we did not close above 43 | if (!s.ok()) { 44 | env->DeleteFile(fname); 45 | } 46 | return s; 47 | } 48 | 49 | Status ReadFileToString(Env* env, const std::string& fname, std::string* data) { 50 | data->clear(); 51 | SequentialFile* file; 52 | Status s = env->NewSequentialFile(fname, &file); 53 | if (!s.ok()) { 54 | return s; 55 | } 56 | static const int kBufferSize = 8192; 57 | char* space = new char[kBufferSize]; 58 | while (true) { 59 | Slice fragment; 60 | s = file->Read(kBufferSize, &fragment, space); 61 | if (!s.ok()) { 62 | break; 63 | } 64 | data->append(fragment.data(), fragment.size()); 65 | if (fragment.empty()) { 66 | break; 67 | } 68 | } 69 | delete[] space; 70 | delete file; 71 | return s; 72 | } 73 | 74 | EnvWrapper::~EnvWrapper() { 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /deps/leveldb/db/snapshot.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_DB_SNAPSHOT_H_ 6 | #define STORAGE_LEVELDB_DB_SNAPSHOT_H_ 7 | 8 | #include "leveldb/db.h" 9 | 10 | namespace leveldb { 11 | 12 | class SnapshotList; 13 | 14 | // Snapshots are kept in a doubly-linked list in the DB. 15 | // Each SnapshotImpl corresponds to a particular sequence number. 16 | class SnapshotImpl : public Snapshot { 17 | public: 18 | SequenceNumber number_; // const after creation 19 | 20 | private: 21 | friend class SnapshotList; 22 | 23 | // SnapshotImpl is kept in a doubly-linked circular list 24 | SnapshotImpl* prev_; 25 | SnapshotImpl* next_; 26 | 27 | SnapshotList* list_; // just for sanity checks 28 | }; 29 | 30 | class SnapshotList { 31 | public: 32 | SnapshotList() { 33 | list_.prev_ = &list_; 34 | list_.next_ = &list_; 35 | } 36 | 37 | bool empty() const { return list_.next_ == &list_; } 38 | SnapshotImpl* oldest() const { assert(!empty()); return list_.next_; } 39 | SnapshotImpl* newest() const { assert(!empty()); return list_.prev_; } 40 | 41 | const SnapshotImpl* New(SequenceNumber seq) { 42 | SnapshotImpl* s = new SnapshotImpl; 43 | s->number_ = seq; 44 | s->list_ = this; 45 | s->next_ = &list_; 46 | s->prev_ = list_.prev_; 47 | s->prev_->next_ = s; 48 | s->next_->prev_ = s; 49 | return s; 50 | } 51 | 52 | void Delete(const SnapshotImpl* s) { 53 | assert(s->list_ == this); 54 | s->prev_->next_ = s->next_; 55 | s->next_->prev_ = s->prev_; 56 | delete s; 57 | } 58 | 59 | private: 60 | // Dummy head of doubly-linked list of snapshots 61 | SnapshotImpl list_; 62 | }; 63 | 64 | } 65 | 66 | #endif // STORAGE_LEVELDB_DB_SNAPSHOT_H_ 67 | -------------------------------------------------------------------------------- /deps/leveldb/util/testutil.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_UTIL_TESTUTIL_H_ 6 | #define STORAGE_LEVELDB_UTIL_TESTUTIL_H_ 7 | 8 | #include "leveldb/env.h" 9 | #include "leveldb/slice.h" 10 | #include "util/random.h" 11 | 12 | namespace leveldb { 13 | namespace test { 14 | 15 | // Store in *dst a random string of length "len" and return a Slice that 16 | // references the generated data. 17 | extern Slice RandomString(Random* rnd, int len, std::string* dst); 18 | 19 | // Return a random key with the specified length that may contain interesting 20 | // characters (e.g. \x00, \xff, etc.). 21 | extern std::string RandomKey(Random* rnd, int len); 22 | 23 | // Store in *dst a string of length "len" that will compress to 24 | // "N*compressed_fraction" bytes and return a Slice that references 25 | // the generated data. 26 | extern Slice CompressibleString(Random* rnd, double compressed_fraction, 27 | int len, std::string* dst); 28 | 29 | // A wrapper that allows injection of errors. 30 | class ErrorEnv : public EnvWrapper { 31 | public: 32 | bool writable_file_error_; 33 | int num_writable_file_errors_; 34 | 35 | ErrorEnv() : EnvWrapper(Env::Default()), 36 | writable_file_error_(false), 37 | num_writable_file_errors_(0) { } 38 | 39 | virtual Status NewWritableFile(const std::string& fname, 40 | WritableFile** result) { 41 | if (writable_file_error_) { 42 | ++num_writable_file_errors_; 43 | *result = NULL; 44 | return Status::IOError(fname, "fake error"); 45 | } 46 | return target()->NewWritableFile(fname, result); 47 | } 48 | }; 49 | 50 | } 51 | } 52 | 53 | #endif // STORAGE_LEVELDB_UTIL_TESTUTIL_H_ 54 | -------------------------------------------------------------------------------- /deps/leveldb/util/arena_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include "util/arena.h" 6 | 7 | #include "util/random.h" 8 | #include "util/testharness.h" 9 | 10 | namespace leveldb { 11 | 12 | class ArenaTest { }; 13 | 14 | TEST(ArenaTest, Empty) { 15 | Arena arena; 16 | } 17 | 18 | TEST(ArenaTest, Simple) { 19 | std::vector > allocated; 20 | Arena arena; 21 | const int N = 100000; 22 | size_t bytes = 0; 23 | Random rnd(301); 24 | for (int i = 0; i < N; i++) { 25 | size_t s; 26 | if (i % (N / 10) == 0) { 27 | s = i; 28 | } else { 29 | s = rnd.OneIn(4000) ? rnd.Uniform(6000) : 30 | (rnd.OneIn(10) ? rnd.Uniform(100) : rnd.Uniform(20)); 31 | } 32 | if (s == 0) { 33 | // Our arena disallows size 0 allocations. 34 | s = 1; 35 | } 36 | char* r; 37 | if (rnd.OneIn(10)) { 38 | r = arena.AllocateAligned(s); 39 | } else { 40 | r = arena.Allocate(s); 41 | } 42 | 43 | for (int b = 0; b < s; b++) { 44 | // Fill the "i"th allocation with a known bit pattern 45 | r[b] = i % 256; 46 | } 47 | bytes += s; 48 | allocated.push_back(std::make_pair(s, r)); 49 | ASSERT_GE(arena.MemoryUsage(), bytes); 50 | if (i > N/10) { 51 | ASSERT_LE(arena.MemoryUsage(), bytes * 1.10); 52 | } 53 | } 54 | for (int i = 0; i < allocated.size(); i++) { 55 | size_t num_bytes = allocated[i].first; 56 | const char* p = allocated[i].second; 57 | for (int b = 0; b < num_bytes; b++) { 58 | // Check the "i"th allocation for the known bit pattern 59 | ASSERT_EQ(int(p[b]) & 0xff, i % 256); 60 | } 61 | } 62 | } 63 | 64 | } 65 | 66 | int main(int argc, char** argv) { 67 | return leveldb::test::RunAllTests(); 68 | } 69 | -------------------------------------------------------------------------------- /deps/leveldb/table/iterator.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include "leveldb/iterator.h" 6 | #include "util/logging.h" 7 | 8 | namespace leveldb { 9 | 10 | Iterator::Iterator() { 11 | cleanup_.function = NULL; 12 | cleanup_.next = NULL; 13 | } 14 | 15 | Iterator::~Iterator() { 16 | if (cleanup_.function != NULL) { 17 | (*cleanup_.function)(cleanup_.arg1, cleanup_.arg2); 18 | for (Cleanup* c = cleanup_.next; c != NULL; ) { 19 | (*c->function)(c->arg1, c->arg2); 20 | Cleanup* next = c->next; 21 | delete c; 22 | c = next; 23 | } 24 | } 25 | } 26 | 27 | void Iterator::RegisterCleanup(CleanupFunction func, void* arg1, void* arg2) { 28 | assert(func != NULL); 29 | Cleanup* c; 30 | if (cleanup_.function == NULL) { 31 | c = &cleanup_; 32 | } else { 33 | c = new Cleanup; 34 | c->next = cleanup_.next; 35 | cleanup_.next = c; 36 | } 37 | c->function = func; 38 | c->arg1 = arg1; 39 | c->arg2 = arg2; 40 | } 41 | 42 | namespace { 43 | class EmptyIterator : public Iterator { 44 | public: 45 | EmptyIterator(const Status& s) : status_(s) { } 46 | virtual bool Valid() const { return false; } 47 | virtual void Seek(const Slice& target) { } 48 | virtual void SeekToFirst() { } 49 | virtual void SeekToLast() { } 50 | virtual void Next() { assert(false); } 51 | virtual void Prev() { assert(false); } 52 | Slice key() const { assert(false); return Slice(); } 53 | Slice value() const { assert(false); return Slice(); } 54 | virtual Status status() const { return status_; } 55 | private: 56 | Status status_; 57 | }; 58 | } 59 | 60 | Iterator* NewEmptyIterator() { 61 | return new EmptyIterator(Status::OK()); 62 | } 63 | 64 | Iterator* NewErrorIterator(const Status& status) { 65 | return new EmptyIterator(status); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /deps/leveldb/table/block_builder.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_TABLE_BLOCK_BUILDER_H_ 6 | #define STORAGE_LEVELDB_TABLE_BLOCK_BUILDER_H_ 7 | 8 | #include 9 | 10 | #include 11 | #include "leveldb/slice.h" 12 | 13 | namespace leveldb { 14 | 15 | struct Options; 16 | 17 | class BlockBuilder { 18 | public: 19 | explicit BlockBuilder(const Options* options); 20 | 21 | // Reset the contents as if the BlockBuilder was just constructed. 22 | void Reset(); 23 | 24 | // REQUIRES: Finish() has not been callled since the last call to Reset(). 25 | // REQUIRES: key is larger than any previously added key 26 | void Add(const Slice& key, const Slice& value); 27 | 28 | // Finish building the block and return a slice that refers to the 29 | // block contents. The returned slice will remain valid for the 30 | // lifetime of this builder or until Reset() is called. 31 | Slice Finish(); 32 | 33 | // Returns an estimate of the current (uncompressed) size of the block 34 | // we are building. 35 | size_t CurrentSizeEstimate() const; 36 | 37 | // Return true iff no entries have been added since the last Reset() 38 | bool empty() const { 39 | return buffer_.empty(); 40 | } 41 | 42 | private: 43 | const Options* options_; 44 | std::string buffer_; // Destination buffer 45 | std::vector restarts_; // Restart points 46 | int counter_; // Number of entries emitted since restart 47 | bool finished_; // Has Finish() been called? 48 | std::string last_key_; 49 | 50 | // No copying allowed 51 | BlockBuilder(const BlockBuilder&); 52 | void operator=(const BlockBuilder&); 53 | }; 54 | 55 | } 56 | 57 | #endif // STORAGE_LEVELDB_TABLE_BLOCK_BUILDER_H_ 58 | -------------------------------------------------------------------------------- /deps/leveldb/util/crc32c_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include "util/crc32c.h" 6 | #include "util/testharness.h" 7 | 8 | namespace leveldb { 9 | namespace crc32c { 10 | 11 | class CRC { }; 12 | 13 | TEST(CRC, StandardResults) { 14 | // From rfc3720 section B.4. 15 | char buf[32]; 16 | 17 | memset(buf, 0, sizeof(buf)); 18 | ASSERT_EQ(0x8a9136aa, Value(buf, sizeof(buf))); 19 | 20 | memset(buf, 0xff, sizeof(buf)); 21 | ASSERT_EQ(0x62a8ab43, Value(buf, sizeof(buf))); 22 | 23 | for (int i = 0; i < 32; i++) { 24 | buf[i] = i; 25 | } 26 | ASSERT_EQ(0x46dd794e, Value(buf, sizeof(buf))); 27 | 28 | for (int i = 0; i < 32; i++) { 29 | buf[i] = 31 - i; 30 | } 31 | ASSERT_EQ(0x113fdb5c, Value(buf, sizeof(buf))); 32 | 33 | unsigned char data[48] = { 34 | 0x01, 0xc0, 0x00, 0x00, 35 | 0x00, 0x00, 0x00, 0x00, 36 | 0x00, 0x00, 0x00, 0x00, 37 | 0x00, 0x00, 0x00, 0x00, 38 | 0x14, 0x00, 0x00, 0x00, 39 | 0x00, 0x00, 0x04, 0x00, 40 | 0x00, 0x00, 0x00, 0x14, 41 | 0x00, 0x00, 0x00, 0x18, 42 | 0x28, 0x00, 0x00, 0x00, 43 | 0x00, 0x00, 0x00, 0x00, 44 | 0x02, 0x00, 0x00, 0x00, 45 | 0x00, 0x00, 0x00, 0x00, 46 | }; 47 | ASSERT_EQ(0xd9963a56, Value(reinterpret_cast(data), sizeof(data))); 48 | } 49 | 50 | TEST(CRC, Values) { 51 | ASSERT_NE(Value("a", 1), Value("foo", 3)); 52 | } 53 | 54 | TEST(CRC, Extend) { 55 | ASSERT_EQ(Value("hello world", 11), 56 | Extend(Value("hello ", 6), "world", 5)); 57 | } 58 | 59 | TEST(CRC, Mask) { 60 | uint32_t crc = Value("foo", 3); 61 | ASSERT_NE(crc, Mask(crc)); 62 | ASSERT_NE(crc, Mask(Mask(crc))); 63 | ASSERT_EQ(crc, Unmask(Mask(crc))); 64 | ASSERT_EQ(crc, Unmask(Unmask(Mask(Mask(crc))))); 65 | } 66 | 67 | } 68 | } 69 | 70 | int main(int argc, char** argv) { 71 | return leveldb::test::RunAllTests(); 72 | } 73 | -------------------------------------------------------------------------------- /wscript: -------------------------------------------------------------------------------- 1 | from os import system, remove 2 | from os.path import abspath, exists, join 3 | from shutil import rmtree 4 | 5 | srcdir = abspath(".") 6 | blddir = "build" 7 | VERSION = "0.0.1" 8 | 9 | leveldb_dir = join(srcdir, "deps/leveldb") 10 | leveldb_src = ["/db/builder.cc", "/db/db_impl.cc", "/db/db_iter.cc", "/db/filename.cc", "/db/dbformat.cc", "/db/log_reader.cc", "/db/log_writer.cc", "/db/memtable.cc", "/db/repair.cc", "/db/table_cache.cc", "/db/version_edit.cc", "/db/version_set.cc", "/db/write_batch.cc", "/port/port_std.cc", "/table/block.cc", "/table/block_builder.cc", "/table/format.cc", "/table/iterator.cc", "/table/merger.cc", "/table/table.cc", "/table/table_builder.cc", "/table/two_level_iterator.cc", "/util/arena.cc", "/util/cache.cc", "/util/coding.cc", "/util/comparator.cc", "/util/crc32c.cc", "/util/env.cc", "/util/env_posix.cc", "/util/hash.cc", "/util/histogram.cc", "/util/logging.cc", "/util/options.cc", "/util/status.cc"] 11 | leveldb_src = ["deps/leveldb" + path for path in leveldb_src] 12 | 13 | node_leveldb_src = ["src/leveldb.cc", "src/DB.cc", "src/WriteBatch.cc", "src/Iterator.cc", "src/helpers.cc"] 14 | 15 | build_config = join(leveldb_dir, 'build', 'build_config.h') 16 | 17 | def set_options(opt): 18 | opt.tool_options("compiler_cxx") 19 | opt.tool_options("compiler_cc") 20 | 21 | def configure(conf): 22 | conf.check_tool("compiler_cxx") 23 | conf.check_tool("compiler_cc") 24 | conf.check_tool("node_addon") 25 | 26 | if not exists(build_config): 27 | system('cd %s && sh platform.env' % leveldb_dir) 28 | 29 | def clean(ctx): 30 | if exists("build"): rmtree("build") 31 | if exists(build_config): remove(build_config) 32 | 33 | def build(bld): 34 | node_leveldb = bld.new_task_gen("cxx", "shlib", "node_addon") 35 | node_leveldb.source = leveldb_src + node_leveldb_src 36 | node_leveldb.name = "node_leveldb" 37 | node_leveldb.target = "leveldb" 38 | node_leveldb.uselib = ["pthread"] 39 | node_leveldb.includes = [leveldb_dir, leveldb_dir + '/include'] 40 | node_leveldb.cxxflags = ['-O2', '-DNDEBUG', '-DLEVELDB_PLATFORM_STD'] 41 | -------------------------------------------------------------------------------- /deps/leveldb/util/arena.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_UTIL_ARENA_H_ 6 | #define STORAGE_LEVELDB_UTIL_ARENA_H_ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | namespace leveldb { 14 | 15 | class Arena { 16 | public: 17 | Arena(); 18 | ~Arena(); 19 | 20 | // Return a pointer to a newly allocated memory block of "bytes" bytes. 21 | char* Allocate(size_t bytes); 22 | 23 | // Allocate memory with the normal alignment guarantees provided by malloc 24 | char* AllocateAligned(size_t bytes); 25 | 26 | // Returns an estimate of the total memory usage of data allocated 27 | // by the arena (including space allocated but not yet used for user 28 | // allocations). 29 | size_t MemoryUsage() const { 30 | return blocks_memory_ + blocks_.capacity() * sizeof(char*); 31 | } 32 | 33 | private: 34 | char* AllocateFallback(size_t bytes); 35 | char* AllocateNewBlock(size_t block_bytes); 36 | 37 | // Allocation state 38 | char* alloc_ptr_; 39 | size_t alloc_bytes_remaining_; 40 | 41 | // Array of new[] allocated memory blocks 42 | std::vector blocks_; 43 | 44 | // Bytes of memory in blocks allocated so far 45 | size_t blocks_memory_; 46 | 47 | // No copying allowed 48 | Arena(const Arena&); 49 | void operator=(const Arena&); 50 | }; 51 | 52 | inline char* Arena::Allocate(size_t bytes) { 53 | // The semantics of what to return are a bit messy if we allow 54 | // 0-byte allocations, so we disallow them here (we don't need 55 | // them for our internal use). 56 | assert(bytes > 0); 57 | if (bytes <= alloc_bytes_remaining_) { 58 | char* result = alloc_ptr_; 59 | alloc_ptr_ += bytes; 60 | alloc_bytes_remaining_ -= bytes; 61 | return result; 62 | } 63 | return AllocateFallback(bytes); 64 | } 65 | 66 | } 67 | 68 | #endif // STORAGE_LEVELDB_UTIL_ARENA_H_ 69 | -------------------------------------------------------------------------------- /deps/leveldb/include/leveldb/write_batch.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | // 5 | // WriteBatch holds a collection of updates to apply atomically to a DB. 6 | // 7 | // The updates are applied in the order in which they are added 8 | // to the WriteBatch. For example, the value of "key" will be "v3" 9 | // after the following batch is written: 10 | // 11 | // batch.Put("key", "v1"); 12 | // batch.Delete("key"); 13 | // batch.Put("key", "v2"); 14 | // batch.Put("key", "v3"); 15 | // 16 | // Multiple threads can invoke const methods on a WriteBatch without 17 | // external synchronization, but if any of the threads may call a 18 | // non-const method, all threads accessing the same WriteBatch must use 19 | // external synchronization. 20 | 21 | #ifndef STORAGE_LEVELDB_INCLUDE_WRITE_BATCH_H_ 22 | #define STORAGE_LEVELDB_INCLUDE_WRITE_BATCH_H_ 23 | 24 | #include 25 | #include "leveldb/status.h" 26 | 27 | namespace leveldb { 28 | 29 | class Slice; 30 | 31 | class WriteBatch { 32 | public: 33 | WriteBatch(); 34 | ~WriteBatch(); 35 | 36 | // Store the mapping "key->value" in the database. 37 | void Put(const Slice& key, const Slice& value); 38 | 39 | // If the database contains a mapping for "key", erase it. Else do nothing. 40 | void Delete(const Slice& key); 41 | 42 | // Clear all updates buffered in this batch. 43 | void Clear(); 44 | 45 | // Support for iterating over the contents of a batch. 46 | class Handler { 47 | public: 48 | virtual ~Handler(); 49 | virtual void Put(const Slice& key, const Slice& value) = 0; 50 | virtual void Delete(const Slice& key) = 0; 51 | }; 52 | Status Iterate(Handler* handler) const; 53 | 54 | private: 55 | friend class WriteBatchInternal; 56 | 57 | std::string rep_; // See comment in write_batch.cc for the format of rep_ 58 | 59 | // Intentionally copyable 60 | }; 61 | 62 | } 63 | 64 | #endif // STORAGE_LEVELDB_INCLUDE_WRITE_BATCH_H_ 65 | -------------------------------------------------------------------------------- /deps/leveldb/util/logging.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include "util/logging.h" 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "leveldb/env.h" 12 | #include "leveldb/slice.h" 13 | 14 | namespace leveldb { 15 | 16 | void AppendNumberTo(std::string* str, uint64_t num) { 17 | char buf[30]; 18 | snprintf(buf, sizeof(buf), "%llu", (unsigned long long) num); 19 | str->append(buf); 20 | } 21 | 22 | void AppendEscapedStringTo(std::string* str, const Slice& value) { 23 | for (size_t i = 0; i < value.size(); i++) { 24 | char c = value[i]; 25 | if (c >= ' ' && c <= '~') { 26 | str->push_back(c); 27 | } else { 28 | char buf[10]; 29 | snprintf(buf, sizeof(buf), "\\x%02x", 30 | static_cast(c) & 0xff); 31 | str->append(buf); 32 | } 33 | } 34 | } 35 | 36 | std::string NumberToString(uint64_t num) { 37 | std::string r; 38 | AppendNumberTo(&r, num); 39 | return r; 40 | } 41 | 42 | std::string EscapeString(const Slice& value) { 43 | std::string r; 44 | AppendEscapedStringTo(&r, value); 45 | return r; 46 | } 47 | 48 | bool ConsumeChar(Slice* in, char c) { 49 | if (!in->empty() && (*in)[0] == c) { 50 | in->remove_prefix(1); 51 | return true; 52 | } else { 53 | return false; 54 | } 55 | } 56 | 57 | bool ConsumeDecimalNumber(Slice* in, uint64_t* val) { 58 | uint64_t v = 0; 59 | int digits = 0; 60 | while (!in->empty()) { 61 | char c = (*in)[0]; 62 | if (c >= '0' && c <= '9') { 63 | ++digits; 64 | const int delta = (c - '0'); 65 | static const uint64_t kMaxUint64 = ~static_cast(0); 66 | if (v > kMaxUint64/10 || 67 | (v == kMaxUint64/10 && delta > kMaxUint64%10)) { 68 | // Overflow 69 | return false; 70 | } 71 | v = (v * 10) + delta; 72 | in->remove_prefix(1); 73 | } else { 74 | break; 75 | } 76 | } 77 | *val = v; 78 | return (digits > 0); 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /deps/leveldb/table/iterator_wrapper.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_TABLE_ITERATOR_WRAPPER_H_ 6 | #define STORAGE_LEVELDB_TABLE_ITERATOR_WRAPPER_H_ 7 | 8 | namespace leveldb { 9 | 10 | // A internal wrapper class with an interface similar to Iterator that 11 | // caches the valid() and key() results for an underlying iterator. 12 | // This can help avoid virtual function calls and also gives better 13 | // cache locality. 14 | class IteratorWrapper { 15 | private: 16 | Iterator* iter_; 17 | bool valid_; 18 | Slice key_; 19 | public: 20 | IteratorWrapper(): iter_(NULL), valid_(false) { } 21 | explicit IteratorWrapper(Iterator* iter): iter_(NULL) { 22 | Set(iter); 23 | } 24 | ~IteratorWrapper() { delete iter_; } 25 | Iterator* iter() const { return iter_; } 26 | 27 | // Takes ownership of "iter" and will delete it when destroyed, or 28 | // when Set() is invoked again. 29 | void Set(Iterator* iter) { 30 | delete iter_; 31 | iter_ = iter; 32 | if (iter_ == NULL) { 33 | valid_ = false; 34 | } else { 35 | Update(); 36 | } 37 | } 38 | 39 | 40 | // Iterator interface methods 41 | bool Valid() const { return valid_; } 42 | Slice key() const { assert(Valid()); return key_; } 43 | Slice value() const { assert(Valid()); return iter_->value(); } 44 | // Methods below require iter() != NULL 45 | Status status() const { assert(iter_); return iter_->status(); } 46 | void Next() { assert(iter_); iter_->Next(); Update(); } 47 | void Prev() { assert(iter_); iter_->Prev(); Update(); } 48 | void Seek(const Slice& k) { assert(iter_); iter_->Seek(k); Update(); } 49 | void SeekToFirst() { assert(iter_); iter_->SeekToFirst(); Update(); } 50 | void SeekToLast() { assert(iter_); iter_->SeekToLast(); Update(); } 51 | 52 | private: 53 | void Update() { 54 | valid_ = iter_->Valid(); 55 | if (valid_) { 56 | key_ = iter_->key(); 57 | } 58 | } 59 | }; 60 | 61 | } 62 | 63 | 64 | #endif // STORAGE_LEVELDB_TABLE_ITERATOR_WRAPPER_H_ 65 | -------------------------------------------------------------------------------- /src/Iterator.h: -------------------------------------------------------------------------------- 1 | #ifndef ITERATOR_H_ 2 | #define ITERATOR_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "leveldb/iterator.h" 8 | 9 | using namespace v8; 10 | using namespace node; 11 | 12 | namespace node_leveldb { 13 | 14 | class Iterator : ObjectWrap { 15 | public: 16 | Iterator(); 17 | ~Iterator(); 18 | 19 | static Persistent persistent_function_template; 20 | static void Init(Handle target); 21 | static Handle New(const Arguments& args); 22 | 23 | static Handle Valid(const Arguments& args); 24 | static Handle SeekToFirst(const Arguments& args); 25 | static Handle SeekToLast(const Arguments& args); 26 | static Handle Seek(const Arguments& args); 27 | static Handle Next(const Arguments& args); 28 | static Handle Prev(const Arguments& args); 29 | 30 | static Handle key(const Arguments& args); 31 | static Handle value(const Arguments& args); 32 | static Handle status(const Arguments& args); 33 | 34 | private: 35 | leveldb::Iterator* it; 36 | 37 | struct SeekParams { 38 | SeekParams(Iterator* it, leveldb::Slice k, Handle cb) { 39 | self = it; 40 | key = k; 41 | callback = Persistent::New(cb); 42 | 43 | self->Ref(); 44 | ev_ref(EV_DEFAULT_UC); 45 | } 46 | 47 | ~SeekParams() { 48 | self->Unref(); 49 | ev_unref(EV_DEFAULT_UC); 50 | callback.Dispose(); 51 | } 52 | 53 | virtual void Callback(Handle result = Handle()); 54 | 55 | Iterator* self; 56 | leveldb::Slice key; 57 | Persistent callback; 58 | 59 | }; 60 | 61 | static void EIO_BeforeSeek(SeekParams *params); 62 | static int EIO_Seek(eio_req *req); 63 | 64 | static void EIO_BeforeSeekToLast(SeekParams *params); 65 | static int EIO_SeekToLast(eio_req *req); 66 | 67 | static void EIO_BeforeSeekToFirst(SeekParams *params); 68 | static int EIO_SeekToFirst(eio_req *req); 69 | 70 | static int EIO_AfterSeek(eio_req *req); 71 | }; 72 | 73 | } // node_leveldb 74 | 75 | #endif 76 | 77 | -------------------------------------------------------------------------------- /deps/leveldb/util/status.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include 6 | #include "port/port.h" 7 | #include "leveldb/status.h" 8 | 9 | namespace leveldb { 10 | 11 | const char* Status::CopyState(const char* state) { 12 | uint32_t size; 13 | memcpy(&size, state, sizeof(size)); 14 | char* result = new char[size + 5]; 15 | memcpy(result, state, size + 5); 16 | return result; 17 | } 18 | 19 | Status::Status(Code code, const Slice& msg, const Slice& msg2) { 20 | assert(code != kOk); 21 | const uint32_t len1 = msg.size(); 22 | const uint32_t len2 = msg2.size(); 23 | const uint32_t size = len1 + (len2 ? (2 + len2) : 0); 24 | char* result = new char[size + 5]; 25 | memcpy(result, &size, sizeof(size)); 26 | result[4] = static_cast(code); 27 | memcpy(result + 5, msg.data(), len1); 28 | if (len2) { 29 | result[5 + len1] = ':'; 30 | result[6 + len1] = ' '; 31 | memcpy(result + 7 + len1, msg2.data(), len2); 32 | } 33 | state_ = result; 34 | } 35 | 36 | std::string Status::ToString() const { 37 | if (state_ == NULL) { 38 | return "OK"; 39 | } else { 40 | char tmp[30]; 41 | const char* type; 42 | switch (code()) { 43 | case kOk: 44 | type = "OK"; 45 | break; 46 | case kNotFound: 47 | type = "NotFound: "; 48 | break; 49 | case kCorruption: 50 | type = "Corruption: "; 51 | break; 52 | case kNotSupported: 53 | type = "Not implemented: "; 54 | break; 55 | case kInvalidArgument: 56 | type = "Invalid argument: "; 57 | break; 58 | case kIOError: 59 | type = "IO error: "; 60 | break; 61 | default: 62 | snprintf(tmp, sizeof(tmp), "Unknown code(%d): ", 63 | static_cast(code())); 64 | type = tmp; 65 | break; 66 | } 67 | std::string result(type); 68 | uint32_t length; 69 | memcpy(&length, state_, sizeof(length)); 70 | result.append(state_ + 5, length); 71 | return result; 72 | } 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /deps/leveldb/util/arena.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include "util/arena.h" 6 | #include 7 | 8 | namespace leveldb { 9 | 10 | static const int kBlockSize = 4096; 11 | 12 | Arena::Arena() { 13 | blocks_memory_ = 0; 14 | alloc_ptr_ = NULL; // First allocation will allocate a block 15 | alloc_bytes_remaining_ = 0; 16 | } 17 | 18 | Arena::~Arena() { 19 | for (size_t i = 0; i < blocks_.size(); i++) { 20 | delete[] blocks_[i]; 21 | } 22 | } 23 | 24 | char* Arena::AllocateFallback(size_t bytes) { 25 | if (bytes > kBlockSize / 4) { 26 | // Object is more than a quarter of our block size. Allocate it separately 27 | // to avoid wasting too much space in leftover bytes. 28 | char* result = AllocateNewBlock(bytes); 29 | return result; 30 | } 31 | 32 | // We waste the remaining space in the current block. 33 | alloc_ptr_ = AllocateNewBlock(kBlockSize); 34 | alloc_bytes_remaining_ = kBlockSize; 35 | 36 | char* result = alloc_ptr_; 37 | alloc_ptr_ += bytes; 38 | alloc_bytes_remaining_ -= bytes; 39 | return result; 40 | } 41 | 42 | char* Arena::AllocateAligned(size_t bytes) { 43 | const int align = sizeof(void*); // We'll align to pointer size 44 | assert((align & (align-1)) == 0); // Pointer size should be a power of 2 45 | size_t current_mod = reinterpret_cast(alloc_ptr_) & (align-1); 46 | size_t slop = (current_mod == 0 ? 0 : align - current_mod); 47 | size_t needed = bytes + slop; 48 | char* result; 49 | if (needed <= alloc_bytes_remaining_) { 50 | result = alloc_ptr_ + slop; 51 | alloc_ptr_ += needed; 52 | alloc_bytes_remaining_ -= needed; 53 | } else { 54 | // AllocateFallback always returned aligned memory 55 | result = AllocateFallback(bytes); 56 | } 57 | assert((reinterpret_cast(result) & (align-1)) == 0); 58 | return result; 59 | } 60 | 61 | char* Arena::AllocateNewBlock(size_t block_bytes) { 62 | char* result = new char[block_bytes]; 63 | blocks_memory_ += block_bytes; 64 | blocks_.push_back(result); 65 | return result; 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /deps/leveldb/util/comparator.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include 6 | #include "leveldb/comparator.h" 7 | #include "leveldb/slice.h" 8 | #include "util/logging.h" 9 | 10 | namespace leveldb { 11 | 12 | Comparator::~Comparator() { } 13 | 14 | namespace { 15 | class BytewiseComparatorImpl : public Comparator { 16 | public: 17 | BytewiseComparatorImpl() { } 18 | 19 | virtual const char* Name() const { 20 | return "leveldb.BytewiseComparator"; 21 | } 22 | 23 | virtual int Compare(const Slice& a, const Slice& b) const { 24 | return a.compare(b); 25 | } 26 | 27 | virtual void FindShortestSeparator( 28 | std::string* start, 29 | const Slice& limit) const { 30 | // Find length of common prefix 31 | size_t min_length = std::min(start->size(), limit.size()); 32 | size_t diff_index = 0; 33 | while ((diff_index < min_length) && 34 | ((*start)[diff_index] == limit[diff_index])) { 35 | diff_index++; 36 | } 37 | 38 | if (diff_index >= min_length) { 39 | // Do not shorten if one string is a prefix of the other 40 | } else { 41 | uint8_t diff_byte = static_cast((*start)[diff_index]); 42 | if (diff_byte < static_cast(0xff) && 43 | diff_byte + 1 < static_cast(limit[diff_index])) { 44 | (*start)[diff_index]++; 45 | start->resize(diff_index + 1); 46 | assert(Compare(*start, limit) < 0); 47 | } 48 | } 49 | } 50 | 51 | virtual void FindShortSuccessor(std::string* key) const { 52 | // Find first character that can be incremented 53 | size_t n = key->size(); 54 | for (size_t i = 0; i < n; i++) { 55 | const uint8_t byte = (*key)[i]; 56 | if (byte != static_cast(0xff)) { 57 | (*key)[i] = byte + 1; 58 | key->resize(i+1); 59 | return; 60 | } 61 | } 62 | // *key is a run of 0xffs. Leave it alone. 63 | } 64 | }; 65 | } 66 | static const BytewiseComparatorImpl bytewise; 67 | 68 | const Comparator* BytewiseComparator() { 69 | return &bytewise; 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /deps/leveldb/util/random.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_UTIL_RANDOM_H_ 6 | #define STORAGE_LEVELDB_UTIL_RANDOM_H_ 7 | 8 | #include 9 | 10 | namespace leveldb { 11 | 12 | // A very simple random number generator. Not especially good at 13 | // generating truly random bits, but good enough for our needs in this 14 | // package. 15 | class Random { 16 | private: 17 | uint32_t seed_; 18 | public: 19 | explicit Random(uint32_t s) : seed_(s & 0x7fffffffu) { } 20 | uint32_t Next() { 21 | static const uint32_t M = 2147483647L; // 2^31-1 22 | static const uint64_t A = 16807; // bits 14, 8, 7, 5, 2, 1, 0 23 | // We are computing 24 | // seed_ = (seed_ * A) % M, where M = 2^31-1 25 | // 26 | // seed_ must not be zero or M, or else all subsequent computed values 27 | // will be zero or M respectively. For all other values, seed_ will end 28 | // up cycling through every number in [1,M-1] 29 | uint64_t product = seed_ * A; 30 | 31 | // Compute (product % M) using the fact that ((x << 31) % M) == x. 32 | seed_ = static_cast((product >> 31) + (product & M)); 33 | // The first reduction may overflow by 1 bit, so we may need to 34 | // repeat. mod == M is not possible; using > allows the faster 35 | // sign-bit-based test. 36 | if (seed_ > M) { 37 | seed_ -= M; 38 | } 39 | return seed_; 40 | } 41 | // Returns a uniformly distributed value in the range [0..n-1] 42 | // REQUIRES: n > 0 43 | uint32_t Uniform(int n) { return Next() % n; } 44 | 45 | // Randomly returns true ~"1/n" of the time, and false otherwise. 46 | // REQUIRES: n > 0 47 | bool OneIn(int n) { return (Next() % n) == 0; } 48 | 49 | // Skewed: pick "base" uniformly from range [0,max_log] and then 50 | // return "base" random bits. The effect is to pick a number in the 51 | // range [0,2^max_log-1] with exponential bias towards smaller numbers. 52 | uint32_t Skewed(int max_log) { 53 | return Uniform(1 << Uniform(max_log + 1)); 54 | } 55 | }; 56 | 57 | } 58 | 59 | #endif // STORAGE_LEVELDB_UTIL_RANDOM_H_ 60 | -------------------------------------------------------------------------------- /demo/iterator.coffee: -------------------------------------------------------------------------------- 1 | DB = require('../build/default/leveldb.node').DB 2 | uuid = require('node-uuid') 3 | td = require("twisted-deferred") 4 | 5 | start = Date.now() 6 | 7 | entryCount = 1000 8 | readCount = 0 9 | 10 | defer = td.toDeferred 11 | DeferredList = td.DeferredList 12 | 13 | console.log("Creating test database") 14 | path = "/tmp/iterator.db" 15 | db = new DB() 16 | 17 | d = defer(db.open.bind(db), path, {create_if_missing: true}) 18 | d.addCallback () -> 19 | console.log('!! creating ' + entryCount + ' random key entries') 20 | deferreds = [] 21 | for i in [0 .. entryCount] 22 | id = uuid() 23 | 24 | put_d = defer db.put.bind(db), id, JSON.stringify({id: id, name: 'Bob', age: 33}) 25 | deferreds.push(put_d) 26 | 27 | return DeferredList(deferreds) 28 | 29 | d.addCallback () -> 30 | console.log('created in ' + (Date.now() - start) + 'ms') 31 | console.log('!! iterating db in key order') 32 | 33 | # reset the start counter 34 | start = Date.now() 35 | 36 | # iterate over the test database 37 | iterator = db.newIterator({}) 38 | deferred = new td.Deferred() 39 | 40 | iterator.seekToFirst () -> 41 | while iterator.valid() 42 | key = iterator.key().toString('utf8') 43 | 44 | if lastKey && lastKey > key 45 | console.log('found sorting error') 46 | 47 | lastKey = key 48 | readCount++ 49 | 50 | iterator.next() 51 | 52 | console.log('read sequential ' + readCount + ' db contents in ' + (Date.now() - start) + 'ms') 53 | deferred.callback() 54 | 55 | deferred 56 | 57 | d.addCallback () -> 58 | console.log 'Start Seek test' 59 | 60 | deferred = new td.Deferred() 61 | iterator = db.newIterator({}) 62 | testUUID = uuid() 63 | iterator.seek "" + testUUID, () -> 64 | console.log('looking for first key after: ' + testUUID) 65 | # if we found something the report 66 | if (iterator.valid()) 67 | console.log('FOUND: ' + iterator.key().toString('utf-8')) 68 | 69 | deferred.callback() 70 | 71 | deferred 72 | 73 | d.addCallback () -> 74 | console.log "Success" 75 | 76 | d.addErrback (err) -> 77 | console.log err.message.stack 78 | 79 | d.addBoth () -> 80 | db.close() 81 | DB.destroyDB(path, {}) 82 | console.log "Database removed and cleaned up." 83 | 84 | -------------------------------------------------------------------------------- /deps/leveldb/doc/table_format.txt: -------------------------------------------------------------------------------- 1 | File format 2 | =========== 3 | 4 | 5 | [data block 1] 6 | [data block 2] 7 | ... 8 | [data block N] 9 | [meta block 1] 10 | ... 11 | [meta block K] 12 | [metaindex block] 13 | [index block] 14 | [Footer] (fixed size; starts at file_size - sizeof(Footer)) 15 | 16 | 17 | The file contains internal pointers. Each such pointer is called 18 | a BlockHandle and contains the following information: 19 | offset: varint64 20 | size: varint64 21 | 22 | (1) The sequence of key/value pairs in the file are stored in sorted 23 | order and partitioned into a sequence of data blocks. These blocks 24 | come one after another at the beginning of the file. Each data block 25 | is formatted according to the code in block_builder.cc, and then 26 | optionally compressed. 27 | 28 | (2) After the data blocks we store a bunch of meta blocks. The 29 | supported meta block types are described below. More meta block types 30 | may be added in the future. Each meta block is again formatted using 31 | block_builder.cc and then optionally compressed. 32 | 33 | (3) A "metaindex" block. It contains one entry for every other meta 34 | block where the key is the name of the meta block and the value is a 35 | BlockHandle pointing to that meta block. 36 | 37 | (4) An "index" block. This block contains one entry per data block, 38 | where the key is a string >= last key in that data block and before 39 | the first key in the successive data block. The value is the 40 | BlockHandle for the data block. 41 | 42 | (6) At the very end of the file is a fixed length footer that contains 43 | the BlockHandle of the metaindex and index blocks as well as a magic number. 44 | metaindex_handle: char[p]; // Block handle for metaindex 45 | index_handle: char[q]; // Block handle for index 46 | padding: char[40-p-q]; // 0 bytes to make fixed length 47 | // (40==2*BlockHandle::kMaxEncodedLength) 48 | magic: fixed64; // == 0xdb4775248b80fb57 49 | 50 | "stats" Meta Block 51 | ------------------ 52 | 53 | This meta block contains a bunch of stats. The key is the name 54 | of the statistic. The value contains the statistic. 55 | TODO(postrelease): record following stats. 56 | data size 57 | index size 58 | key size (uncompressed) 59 | value size (uncompressed) 60 | number of entries 61 | number of data blocks 62 | -------------------------------------------------------------------------------- /deps/leveldb/base/port.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef BASE_PORT_H_ 6 | #define BASE_PORT_H_ 7 | #pragma once 8 | 9 | #include 10 | #include "build/build_config.h" 11 | 12 | #ifdef COMPILER_MSVC 13 | #define GG_LONGLONG(x) x##I64 14 | #define GG_ULONGLONG(x) x##UI64 15 | #else 16 | #define GG_LONGLONG(x) x##LL 17 | #define GG_ULONGLONG(x) x##ULL 18 | #endif 19 | 20 | // Per C99 7.8.14, define __STDC_CONSTANT_MACROS before including 21 | // to get the INTn_C and UINTn_C macros for integer constants. It's difficult 22 | // to guarantee any specific ordering of header includes, so it's difficult to 23 | // guarantee that the INTn_C macros can be defined by including at 24 | // any specific point. Provide GG_INTn_C macros instead. 25 | 26 | #define GG_INT8_C(x) (x) 27 | #define GG_INT16_C(x) (x) 28 | #define GG_INT32_C(x) (x) 29 | #define GG_INT64_C(x) GG_LONGLONG(x) 30 | 31 | #define GG_UINT8_C(x) (x ## U) 32 | #define GG_UINT16_C(x) (x ## U) 33 | #define GG_UINT32_C(x) (x ## U) 34 | #define GG_UINT64_C(x) GG_ULONGLONG(x) 35 | 36 | // It's possible for functions that use a va_list, such as StringPrintf, to 37 | // invalidate the data in it upon use. The fix is to make a copy of the 38 | // structure before using it and use that copy instead. va_copy is provided 39 | // for this purpose. MSVC does not provide va_copy, so define an 40 | // implementation here. It is not guaranteed that assignment is a copy, so the 41 | // StringUtil.VariableArgsFunc unit test tests this capability. 42 | #if defined(COMPILER_GCC) 43 | #define GG_VA_COPY(a, b) (va_copy(a, b)) 44 | #elif defined(COMPILER_MSVC) 45 | #define GG_VA_COPY(a, b) (a = b) 46 | #endif 47 | 48 | // Define an OS-neutral wrapper for shared library entry points 49 | #if defined(OS_WIN) 50 | #define API_CALL __stdcall 51 | #else 52 | #define API_CALL 53 | #endif 54 | 55 | // Some compilers do not provide access to nested classes of a declared friend class 56 | // Defining PUBLIC_NESTED_FRIEND_ACCESS will cause those declarations to be made public as a workaround 57 | #ifdef PUBLIC_NESTED_FRIEND_ACCESS 58 | #define USED_BY_NESTED_FRIEND(a) public: a; private: 59 | #define USED_BY_NESTED_FRIEND2(a,b) public: a,b; private: 60 | #else 61 | #define USED_BY_NESTED_FRIEND(a) a; 62 | #define USED_BY_NESTED_FRIEND2(a,b) a,b; 63 | #endif 64 | 65 | #endif // BASE_PORT_H_ 66 | -------------------------------------------------------------------------------- /deps/leveldb/port/port_posix.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | // 5 | // See port_example.h for documentation for the following types/functions. 6 | 7 | #ifndef STORAGE_LEVELDB_PORT_PORT_POSIX_H_ 8 | #define STORAGE_LEVELDB_PORT_PORT_POSIX_H_ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | namespace leveldb { 18 | namespace port { 19 | 20 | static const bool kLittleEndian = (__BYTE_ORDER == __LITTLE_ENDIAN); 21 | 22 | class CondVar; 23 | 24 | class Mutex { 25 | public: 26 | Mutex(); 27 | ~Mutex(); 28 | 29 | void Lock(); 30 | void Unlock(); 31 | void AssertHeld() { } 32 | 33 | private: 34 | friend class CondVar; 35 | pthread_mutex_t mu_; 36 | 37 | // No copying 38 | Mutex(const Mutex&); 39 | void operator=(const Mutex&); 40 | }; 41 | 42 | class CondVar { 43 | public: 44 | explicit CondVar(Mutex* mu); 45 | ~CondVar(); 46 | void Wait(); 47 | void Signal(); 48 | void SignalAll(); 49 | private: 50 | pthread_cond_t cv_; 51 | Mutex* mu_; 52 | }; 53 | 54 | // Storage for a lock-free pointer 55 | class AtomicPointer { 56 | private: 57 | std::atomic rep_; 58 | public: 59 | AtomicPointer() { } 60 | explicit AtomicPointer(void* v) : rep_(v) { } 61 | inline void* Acquire_Load() const { 62 | return rep_.load(std::memory_order_acquire); 63 | } 64 | inline void Release_Store(void* v) { 65 | rep_.store(v, std::memory_order_release); 66 | } 67 | inline void* NoBarrier_Load() const { 68 | return rep_.load(std::memory_order_relaxed); 69 | } 70 | inline void NoBarrier_Store(void* v) { 71 | rep_.store(v, std::memory_order_relaxed); 72 | } 73 | }; 74 | 75 | // TODO(gabor): Implement actual compress 76 | inline bool Snappy_Compress(const char* input, size_t input_length, 77 | std::string* output) { 78 | return false; 79 | } 80 | 81 | // TODO(gabor): Implement actual uncompress 82 | inline bool Snappy_Uncompress(const char* input_data, size_t input_length, 83 | std::string* output) { 84 | return false; 85 | } 86 | 87 | inline bool GetHeapProfile(void (*func)(void*, const char*, int), void* arg) { 88 | return false; 89 | } 90 | 91 | } 92 | } 93 | 94 | #endif // STORAGE_LEVELDB_PORT_PORT_POSIX_H_ 95 | -------------------------------------------------------------------------------- /deps/leveldb/include/leveldb/comparator.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_INCLUDE_COMPARATOR_H_ 6 | #define STORAGE_LEVELDB_INCLUDE_COMPARATOR_H_ 7 | 8 | #include 9 | 10 | namespace leveldb { 11 | 12 | class Slice; 13 | 14 | // A Comparator object provides a total order across slices that are 15 | // used as keys in an sstable or a database. A Comparator implementation 16 | // must be thread-safe since leveldb may invoke its methods concurrently 17 | // from multiple threads. 18 | class Comparator { 19 | public: 20 | virtual ~Comparator(); 21 | 22 | // Three-way comparison. Returns value: 23 | // < 0 iff "a" < "b", 24 | // == 0 iff "a" == "b", 25 | // > 0 iff "a" > "b" 26 | virtual int Compare(const Slice& a, const Slice& b) const = 0; 27 | 28 | // The name of the comparator. Used to check for comparator 29 | // mismatches (i.e., a DB created with one comparator is 30 | // accessed using a different comparator. 31 | // 32 | // The client of this package should switch to a new name whenever 33 | // the comparator implementation changes in a way that will cause 34 | // the relative ordering of any two keys to change. 35 | // 36 | // Names starting with "leveldb." are reserved and should not be used 37 | // by any clients of this package. 38 | virtual const char* Name() const = 0; 39 | 40 | // Advanced functions: these are used to reduce the space requirements 41 | // for internal data structures like index blocks. 42 | 43 | // If *start < limit, changes *start to a short string in [start,limit). 44 | // Simple comparator implementations may return with *start unchanged, 45 | // i.e., an implementation of this method that does nothing is correct. 46 | virtual void FindShortestSeparator( 47 | std::string* start, 48 | const Slice& limit) const = 0; 49 | 50 | // Changes *key to a short string >= *key. 51 | // Simple comparator implementations may return with *key unchanged, 52 | // i.e., an implementation of this method that does nothing is correct. 53 | virtual void FindShortSuccessor(std::string* key) const = 0; 54 | }; 55 | 56 | // Return a builtin comparator that uses lexicographic byte-wise 57 | // ordering. The result remains the property of this module and 58 | // must not be deleted. 59 | extern const Comparator* BytewiseComparator(); 60 | 61 | } 62 | 63 | #endif // STORAGE_LEVELDB_INCLUDE_COMPARATOR_H_ 64 | -------------------------------------------------------------------------------- /deps/leveldb/db/builder.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include "db/builder.h" 6 | 7 | #include "db/filename.h" 8 | #include "db/dbformat.h" 9 | #include "db/table_cache.h" 10 | #include "db/version_edit.h" 11 | #include "leveldb/db.h" 12 | #include "leveldb/env.h" 13 | #include "leveldb/iterator.h" 14 | 15 | namespace leveldb { 16 | 17 | Status BuildTable(const std::string& dbname, 18 | Env* env, 19 | const Options& options, 20 | TableCache* table_cache, 21 | Iterator* iter, 22 | FileMetaData* meta, 23 | VersionEdit* edit) { 24 | Status s; 25 | meta->file_size = 0; 26 | iter->SeekToFirst(); 27 | 28 | std::string fname = TableFileName(dbname, meta->number); 29 | if (iter->Valid()) { 30 | WritableFile* file; 31 | s = env->NewWritableFile(fname, &file); 32 | if (!s.ok()) { 33 | return s; 34 | } 35 | 36 | TableBuilder* builder = new TableBuilder(options, file); 37 | meta->smallest.DecodeFrom(iter->key()); 38 | for (; iter->Valid(); iter->Next()) { 39 | Slice key = iter->key(); 40 | meta->largest.DecodeFrom(key); 41 | builder->Add(key, iter->value()); 42 | } 43 | 44 | // Finish and check for builder errors 45 | if (s.ok()) { 46 | s = builder->Finish(); 47 | if (s.ok()) { 48 | meta->file_size = builder->FileSize(); 49 | assert(meta->file_size > 0); 50 | } 51 | } else { 52 | builder->Abandon(); 53 | } 54 | delete builder; 55 | 56 | // Finish and check for file errors 57 | if (s.ok()) { 58 | s = file->Sync(); 59 | } 60 | if (s.ok()) { 61 | s = file->Close(); 62 | } 63 | delete file; 64 | file = NULL; 65 | 66 | if (s.ok()) { 67 | // Verify that the table is usable 68 | Iterator* it = table_cache->NewIterator(ReadOptions(), 69 | meta->number, 70 | meta->file_size); 71 | s = it->status(); 72 | delete it; 73 | } 74 | } 75 | 76 | // Check for input iterator errors 77 | if (!iter->status().ok()) { 78 | s = iter->status(); 79 | } 80 | 81 | if (s.ok() && meta->file_size > 0) { 82 | edit->AddFile(0, meta->number, meta->file_size, 83 | meta->smallest, meta->largest); 84 | } else { 85 | env->DeleteFile(fname); 86 | } 87 | return s; 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /src/WriteBatch.cc: -------------------------------------------------------------------------------- 1 | #include "WriteBatch.h" 2 | 3 | #include 4 | #include "helpers.h" 5 | 6 | using namespace node_leveldb; 7 | 8 | Persistent WriteBatch::persistent_function_template; 9 | 10 | WriteBatch::WriteBatch() { 11 | } 12 | 13 | WriteBatch::~WriteBatch() { 14 | } 15 | 16 | void WriteBatch::Init(Handle target) { 17 | HandleScope scope; 18 | 19 | Local local_function_template = FunctionTemplate::New(New); 20 | persistent_function_template = Persistent::New(local_function_template); 21 | persistent_function_template->InstanceTemplate()->SetInternalFieldCount(1); 22 | persistent_function_template->SetClassName(String::NewSymbol("WriteBatch")); 23 | 24 | NODE_SET_PROTOTYPE_METHOD(persistent_function_template, "put", Put); 25 | NODE_SET_PROTOTYPE_METHOD(persistent_function_template, "del", Del); 26 | NODE_SET_PROTOTYPE_METHOD(persistent_function_template, "clear", Clear); 27 | 28 | target->Set(String::NewSymbol("WriteBatch"), persistent_function_template->GetFunction()); 29 | } 30 | 31 | Handle WriteBatch::New(const Arguments& args) { 32 | HandleScope scope; 33 | 34 | WriteBatch* writeBatch = new WriteBatch(); 35 | writeBatch->Wrap(args.This()); 36 | 37 | return args.This(); 38 | } 39 | 40 | Handle WriteBatch::Put(const Arguments& args) { 41 | HandleScope scope; 42 | 43 | // Check args 44 | if (args.Length() < 2 || (!args[0]->IsString() && !Buffer::HasInstance(args[0])) || (!args[1]->IsString() && !Buffer::HasInstance(args[1]))) { 45 | return ThrowException(Exception::TypeError(String::New("WriteBatch.put() expects key, value"))); 46 | } 47 | 48 | WriteBatch* self = ObjectWrap::Unwrap(args.This()); 49 | 50 | leveldb::Slice key = JsToSlice(args[0], &self->strings); 51 | leveldb::Slice value = JsToSlice(args[1], &self->strings); 52 | 53 | self->wb.Put(key, value); 54 | 55 | return args.This(); 56 | } 57 | 58 | Handle WriteBatch::Del(const Arguments& args) { 59 | HandleScope scope; 60 | 61 | // Check args 62 | if (args.Length() < 1 || (!args[0]->IsString() && !Buffer::HasInstance(args[0]))) { 63 | return ThrowException(Exception::TypeError(String::New("WriteBatch.del() expects key"))); 64 | } 65 | 66 | WriteBatch* self = ObjectWrap::Unwrap(args.This()); 67 | leveldb::Slice key = JsToSlice(args[0], &self->strings); 68 | 69 | self->wb.Delete(key); 70 | 71 | return args.This(); 72 | } 73 | 74 | Handle WriteBatch::Clear(const Arguments& args) { 75 | HandleScope scope; 76 | 77 | WriteBatch* self = ObjectWrap::Unwrap(args.This()); 78 | self->wb.Clear(); 79 | self->strings.clear(); 80 | 81 | return args.This(); 82 | } 83 | -------------------------------------------------------------------------------- /deps/leveldb/include/leveldb/table.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_INCLUDE_TABLE_H_ 6 | #define STORAGE_LEVELDB_INCLUDE_TABLE_H_ 7 | 8 | #include 9 | #include "leveldb/iterator.h" 10 | 11 | namespace leveldb { 12 | 13 | class Block; 14 | class BlockHandle; 15 | struct Options; 16 | class RandomAccessFile; 17 | struct ReadOptions; 18 | 19 | // A Table is a sorted map from strings to strings. Tables are 20 | // immutable and persistent. A Table may be safely accessed from 21 | // multiple threads without external synchronization. 22 | class Table { 23 | public: 24 | // Attempt to open the table that is stored in bytes [0..file_size) 25 | // of "file", and read the metadata entries necessary to allow 26 | // retrieving data from the table. 27 | // 28 | // If successful, returns ok and sets "*table" to the newly opened 29 | // table. The client should delete "*table" when no longer needed. 30 | // If there was an error while initializing the table, sets "*table" 31 | // to NULL and returns a non-ok status. Does not take ownership of 32 | // "*source", but the client must ensure that "source" remains live 33 | // for the duration of the returned table's lifetime. 34 | // 35 | // *file must remain live while this Table is in use. 36 | static Status Open(const Options& options, 37 | RandomAccessFile* file, 38 | uint64_t file_size, 39 | Table** table); 40 | 41 | ~Table(); 42 | 43 | // Returns a new iterator over the table contents. 44 | // The result of NewIterator() is initially invalid (caller must 45 | // call one of the Seek methods on the iterator before using it). 46 | Iterator* NewIterator(const ReadOptions&) const; 47 | 48 | // Given a key, return an approximate byte offset in the file where 49 | // the data for that key begins (or would begin if the key were 50 | // present in the file). The returned value is in terms of file 51 | // bytes, and so includes effects like compression of the underlying data. 52 | // E.g., the approximate offset of the last key in the table will 53 | // be close to the file length. 54 | uint64_t ApproximateOffsetOf(const Slice& key) const; 55 | 56 | private: 57 | struct Rep; 58 | Rep* rep_; 59 | 60 | explicit Table(Rep* rep) { rep_ = rep; } 61 | static Iterator* BlockReader(void*, const ReadOptions&, const Slice&); 62 | 63 | // No copying allowed 64 | Table(const Table&); 65 | void operator=(const Table&); 66 | }; 67 | 68 | } 69 | 70 | #endif // STORAGE_LEVELDB_INCLUDE_TABLE_H_ 71 | -------------------------------------------------------------------------------- /deps/leveldb/util/env_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include "leveldb/env.h" 6 | 7 | #include "port/port.h" 8 | #include "util/testharness.h" 9 | 10 | namespace leveldb { 11 | 12 | static const int kDelayMicros = 100000; 13 | 14 | class EnvPosixTest { 15 | private: 16 | port::Mutex mu_; 17 | std::string events_; 18 | 19 | public: 20 | Env* env_; 21 | EnvPosixTest() : env_(Env::Default()) { } 22 | }; 23 | 24 | static void SetBool(void* ptr) { 25 | *(reinterpret_cast(ptr)) = true; 26 | } 27 | 28 | TEST(EnvPosixTest, RunImmediately) { 29 | bool called = false; 30 | env_->Schedule(&SetBool, &called); 31 | Env::Default()->SleepForMicroseconds(kDelayMicros); 32 | ASSERT_TRUE(called); 33 | } 34 | 35 | TEST(EnvPosixTest, RunMany) { 36 | int last_id = 0; 37 | 38 | struct CB { 39 | int* last_id_ptr; // Pointer to shared slot 40 | int id; // Order# for the execution of this callback 41 | 42 | CB(int* p, int i) : last_id_ptr(p), id(i) { } 43 | 44 | static void Run(void* v) { 45 | CB* cb = reinterpret_cast(v); 46 | ASSERT_EQ(cb->id-1, *cb->last_id_ptr); 47 | *cb->last_id_ptr = cb->id; 48 | } 49 | }; 50 | 51 | // Schedule in different order than start time 52 | CB cb1(&last_id, 1); 53 | CB cb2(&last_id, 2); 54 | CB cb3(&last_id, 3); 55 | CB cb4(&last_id, 4); 56 | env_->Schedule(&CB::Run, &cb1); 57 | env_->Schedule(&CB::Run, &cb2); 58 | env_->Schedule(&CB::Run, &cb3); 59 | env_->Schedule(&CB::Run, &cb4); 60 | 61 | Env::Default()->SleepForMicroseconds(kDelayMicros); 62 | ASSERT_EQ(4, last_id); 63 | } 64 | 65 | struct State { 66 | port::Mutex mu; 67 | int val; 68 | int num_running; 69 | }; 70 | 71 | static void ThreadBody(void* arg) { 72 | State* s = reinterpret_cast(arg); 73 | s->mu.Lock(); 74 | s->val += 1; 75 | s->num_running -= 1; 76 | s->mu.Unlock(); 77 | } 78 | 79 | TEST(EnvPosixTest, StartThread) { 80 | State state; 81 | state.val = 0; 82 | state.num_running = 3; 83 | for (int i = 0; i < 3; i++) { 84 | env_->StartThread(&ThreadBody, &state); 85 | } 86 | while (true) { 87 | state.mu.Lock(); 88 | int num = state.num_running; 89 | state.mu.Unlock(); 90 | if (num == 0) { 91 | break; 92 | } 93 | Env::Default()->SleepForMicroseconds(kDelayMicros); 94 | } 95 | ASSERT_EQ(state.val, 3); 96 | } 97 | 98 | } 99 | 100 | int main(int argc, char** argv) { 101 | return leveldb::test::RunAllTests(); 102 | } 103 | -------------------------------------------------------------------------------- /deps/leveldb/port/port_chromium.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | // 5 | // See port_example.h for documentation for the following types/functions. 6 | 7 | #ifndef STORAGE_LEVELDB_PORT_PORT_CHROMIUM_H_ 8 | #define STORAGE_LEVELDB_PORT_PORT_CHROMIUM_H_ 9 | 10 | #include 11 | #include 12 | #include 13 | #include "base/atomicops.h" 14 | #include "base/basictypes.h" 15 | #include "base/logging.h" 16 | #include "base/synchronization/condition_variable.h" 17 | #include "base/synchronization/lock.h" 18 | 19 | // Linux's ThreadIdentifier() needs this. 20 | #if defined(OS_LINUX) 21 | # include 22 | #endif 23 | 24 | #if defined(OS_WIN) 25 | #define snprintf _snprintf 26 | #define va_copy(a, b) do { (a) = (b); } while (0) 27 | #endif 28 | 29 | namespace leveldb { 30 | namespace port { 31 | 32 | // Chromium only supports little endian. 33 | static const bool kLittleEndian = true; 34 | 35 | class Mutex { 36 | public: 37 | Mutex(); 38 | ~Mutex(); 39 | void Lock(); 40 | void Unlock(); 41 | void AssertHeld(); 42 | 43 | private: 44 | base::Lock mu_; 45 | 46 | friend class CondVar; 47 | DISALLOW_COPY_AND_ASSIGN(Mutex); 48 | }; 49 | 50 | class CondVar { 51 | public: 52 | explicit CondVar(Mutex* mu); 53 | ~CondVar(); 54 | void Wait(); 55 | void Signal(); 56 | void SignalAll(); 57 | 58 | private: 59 | base::ConditionVariable cv_; 60 | 61 | DISALLOW_COPY_AND_ASSIGN(CondVar); 62 | }; 63 | 64 | class AtomicPointer { 65 | private: 66 | typedef base::subtle::AtomicWord Rep; 67 | Rep rep_; 68 | public: 69 | AtomicPointer() { } 70 | explicit AtomicPointer(void* p) : rep_(reinterpret_cast(p)) {} 71 | inline void* Acquire_Load() const { 72 | return reinterpret_cast(::base::subtle::Acquire_Load(&rep_)); 73 | } 74 | inline void Release_Store(void* v) { 75 | ::base::subtle::Release_Store(&rep_, reinterpret_cast(v)); 76 | } 77 | inline void* NoBarrier_Load() const { 78 | return reinterpret_cast(::base::subtle::NoBarrier_Load(&rep_)); 79 | } 80 | inline void NoBarrier_Store(void* v) { 81 | ::base::subtle::NoBarrier_Store(&rep_, reinterpret_cast(v)); 82 | } 83 | }; 84 | 85 | bool Snappy_Compress(const char* input, size_t input_length, 86 | std::string* output); 87 | bool Snappy_Uncompress(const char* input_data, size_t input_length, 88 | std::string* output); 89 | 90 | inline bool GetHeapProfile(void (*func)(void*, const char*, int), void* arg) { 91 | return false; 92 | } 93 | 94 | } 95 | } 96 | 97 | #endif // STORAGE_LEVELDB_PORT_PORT_CHROMIUM_H_ 98 | -------------------------------------------------------------------------------- /deps/leveldb/db/memtable.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_DB_MEMTABLE_H_ 6 | #define STORAGE_LEVELDB_DB_MEMTABLE_H_ 7 | 8 | #include 9 | #include "leveldb/db.h" 10 | #include "db/dbformat.h" 11 | #include "db/skiplist.h" 12 | #include "util/arena.h" 13 | 14 | namespace leveldb { 15 | 16 | class InternalKeyComparator; 17 | class Mutex; 18 | class MemTableIterator; 19 | 20 | class MemTable { 21 | public: 22 | // MemTables are reference counted. The initial reference count 23 | // is zero and the caller must call Ref() at least once. 24 | explicit MemTable(const InternalKeyComparator& comparator); 25 | 26 | // Increase reference count. 27 | void Ref() { ++refs_; } 28 | 29 | // Drop reference count. Delete if no more references exist. 30 | void Unref() { 31 | --refs_; 32 | assert(refs_ >= 0); 33 | if (refs_ <= 0) { 34 | delete this; 35 | } 36 | } 37 | 38 | // Returns an estimate of the number of bytes of data in use by this 39 | // data structure. 40 | // 41 | // REQUIRES: external synchronization to prevent simultaneous 42 | // operations on the same MemTable. 43 | size_t ApproximateMemoryUsage(); 44 | 45 | // Return an iterator that yields the contents of the memtable. 46 | // 47 | // The caller must ensure that the underlying MemTable remains live 48 | // while the returned iterator is live. The keys returned by this 49 | // iterator are internal keys encoded by AppendInternalKey in the 50 | // db/format.{h,cc} module. 51 | Iterator* NewIterator(); 52 | 53 | // Add an entry into memtable that maps key to value at the 54 | // specified sequence number and with the specified type. 55 | // Typically value will be empty if type==kTypeDeletion. 56 | void Add(SequenceNumber seq, ValueType type, 57 | const Slice& key, 58 | const Slice& value); 59 | 60 | private: 61 | ~MemTable(); // Private since only Unref() should be used to delete it 62 | 63 | struct KeyComparator { 64 | const InternalKeyComparator comparator; 65 | explicit KeyComparator(const InternalKeyComparator& c) : comparator(c) { } 66 | int operator()(const char* a, const char* b) const; 67 | }; 68 | friend class MemTableIterator; 69 | friend class MemTableBackwardIterator; 70 | 71 | typedef SkipList Table; 72 | 73 | KeyComparator comparator_; 74 | int refs_; 75 | Arena arena_; 76 | Table table_; 77 | 78 | // No copying allowed 79 | MemTable(const MemTable&); 80 | void operator=(const MemTable&); 81 | }; 82 | 83 | } 84 | 85 | #endif // STORAGE_LEVELDB_DB_MEMTABLE_H_ 86 | -------------------------------------------------------------------------------- /deps/leveldb/db/write_batch_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include "leveldb/db.h" 6 | 7 | #include "db/memtable.h" 8 | #include "db/write_batch_internal.h" 9 | #include "leveldb/env.h" 10 | #include "util/logging.h" 11 | #include "util/testharness.h" 12 | 13 | namespace leveldb { 14 | 15 | static std::string PrintContents(WriteBatch* b) { 16 | InternalKeyComparator cmp(BytewiseComparator()); 17 | MemTable* mem = new MemTable(cmp); 18 | mem->Ref(); 19 | std::string state; 20 | Status s = WriteBatchInternal::InsertInto(b, mem); 21 | Iterator* iter = mem->NewIterator(); 22 | for (iter->SeekToFirst(); iter->Valid(); iter->Next()) { 23 | ParsedInternalKey ikey; 24 | ASSERT_TRUE(ParseInternalKey(iter->key(), &ikey)); 25 | switch (ikey.type) { 26 | case kTypeValue: 27 | state.append("Put("); 28 | state.append(ikey.user_key.ToString()); 29 | state.append(", "); 30 | state.append(iter->value().ToString()); 31 | state.append(")"); 32 | break; 33 | case kTypeDeletion: 34 | state.append("Delete("); 35 | state.append(ikey.user_key.ToString()); 36 | state.append(")"); 37 | break; 38 | } 39 | state.append("@"); 40 | state.append(NumberToString(ikey.sequence)); 41 | } 42 | delete iter; 43 | if (!s.ok()) { 44 | state.append("ParseError()"); 45 | } 46 | mem->Unref(); 47 | return state; 48 | } 49 | 50 | class WriteBatchTest { }; 51 | 52 | TEST(WriteBatchTest, Empty) { 53 | WriteBatch batch; 54 | ASSERT_EQ("", PrintContents(&batch)); 55 | ASSERT_EQ(0, WriteBatchInternal::Count(&batch)); 56 | } 57 | 58 | TEST(WriteBatchTest, Multiple) { 59 | WriteBatch batch; 60 | batch.Put(Slice("foo"), Slice("bar")); 61 | batch.Delete(Slice("box")); 62 | batch.Put(Slice("baz"), Slice("boo")); 63 | WriteBatchInternal::SetSequence(&batch, 100); 64 | ASSERT_EQ(100, WriteBatchInternal::Sequence(&batch)); 65 | ASSERT_EQ(3, WriteBatchInternal::Count(&batch)); 66 | ASSERT_EQ("Put(baz, boo)@102" 67 | "Delete(box)@101" 68 | "Put(foo, bar)@100", 69 | PrintContents(&batch)); 70 | } 71 | 72 | TEST(WriteBatchTest, Corruption) { 73 | WriteBatch batch; 74 | batch.Put(Slice("foo"), Slice("bar")); 75 | batch.Delete(Slice("box")); 76 | WriteBatchInternal::SetSequence(&batch, 200); 77 | Slice contents = WriteBatchInternal::Contents(&batch); 78 | WriteBatchInternal::SetContents(&batch, 79 | Slice(contents.data(),contents.size()-1)); 80 | ASSERT_EQ("Put(foo, bar)@200" 81 | "ParseError()", 82 | PrintContents(&batch)); 83 | } 84 | 85 | } 86 | 87 | int main(int argc, char** argv) { 88 | return leveldb::test::RunAllTests(); 89 | } 90 | -------------------------------------------------------------------------------- /deps/leveldb/db/table_cache.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include "db/table_cache.h" 6 | 7 | #include "db/filename.h" 8 | #include "leveldb/env.h" 9 | #include "leveldb/table.h" 10 | #include "util/coding.h" 11 | 12 | namespace leveldb { 13 | 14 | struct TableAndFile { 15 | RandomAccessFile* file; 16 | Table* table; 17 | }; 18 | 19 | static void DeleteEntry(const Slice& key, void* value) { 20 | TableAndFile* tf = reinterpret_cast(value); 21 | delete tf->table; 22 | delete tf->file; 23 | delete tf; 24 | } 25 | 26 | static void UnrefEntry(void* arg1, void* arg2) { 27 | Cache* cache = reinterpret_cast(arg1); 28 | Cache::Handle* h = reinterpret_cast(arg2); 29 | cache->Release(h); 30 | } 31 | 32 | TableCache::TableCache(const std::string& dbname, 33 | const Options* options, 34 | int entries) 35 | : env_(options->env), 36 | dbname_(dbname), 37 | options_(options), 38 | cache_(NewLRUCache(entries)) { 39 | } 40 | 41 | TableCache::~TableCache() { 42 | delete cache_; 43 | } 44 | 45 | Iterator* TableCache::NewIterator(const ReadOptions& options, 46 | uint64_t file_number, 47 | uint64_t file_size, 48 | Table** tableptr) { 49 | if (tableptr != NULL) { 50 | *tableptr = NULL; 51 | } 52 | 53 | char buf[sizeof(file_number)]; 54 | EncodeFixed64(buf, file_number); 55 | Slice key(buf, sizeof(buf)); 56 | Cache::Handle* handle = cache_->Lookup(key); 57 | if (handle == NULL) { 58 | std::string fname = TableFileName(dbname_, file_number); 59 | RandomAccessFile* file = NULL; 60 | Table* table = NULL; 61 | Status s = env_->NewRandomAccessFile(fname, &file); 62 | if (s.ok()) { 63 | s = Table::Open(*options_, file, file_size, &table); 64 | } 65 | 66 | if (!s.ok()) { 67 | assert(table == NULL); 68 | delete file; 69 | // We do not cache error results so that if the error is transient, 70 | // or somebody repairs the file, we recover automatically. 71 | return NewErrorIterator(s); 72 | } 73 | 74 | TableAndFile* tf = new TableAndFile; 75 | tf->file = file; 76 | tf->table = table; 77 | handle = cache_->Insert(key, tf, 1, &DeleteEntry); 78 | } 79 | 80 | Table* table = reinterpret_cast(cache_->Value(handle))->table; 81 | Iterator* result = table->NewIterator(options); 82 | result->RegisterCleanup(&UnrefEntry, cache_, handle); 83 | if (tableptr != NULL) { 84 | *tableptr = table; 85 | } 86 | return result; 87 | } 88 | 89 | void TableCache::Evict(uint64_t file_number) { 90 | char buf[sizeof(file_number)]; 91 | EncodeFixed64(buf, file_number); 92 | cache_->Erase(Slice(buf, sizeof(buf))); 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /deps/leveldb/port/port_std.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | // 5 | // See port_example.h for documentation for the following types/functions. 6 | 7 | #ifndef STORAGE_LEVELDB_PORT_PORT_STD_H_ 8 | #define STORAGE_LEVELDB_PORT_PORT_STD_H_ 9 | 10 | #include "build/build_config.h" 11 | #if defined(OS_MACOSX) 12 | #include 13 | #else 14 | #include 15 | #endif 16 | #include 17 | #include 18 | #include 19 | #include "base/atomicops.h" 20 | 21 | #define fread_unlocked fread 22 | #define fwrite_unlocked fwrite 23 | #define fflush_unlocked fflush 24 | #if defined(OS_MACOSX) 25 | #define fdatasync fsync 26 | #endif 27 | 28 | namespace leveldb { 29 | namespace port { 30 | 31 | static const bool kLittleEndian = (BYTE_ORDER == LITTLE_ENDIAN); 32 | 33 | class CondVar; 34 | 35 | class Mutex { 36 | public: 37 | Mutex(); 38 | ~Mutex(); 39 | 40 | void Lock(); 41 | void Unlock(); 42 | void AssertHeld() { } 43 | 44 | private: 45 | friend class CondVar; 46 | pthread_mutex_t mu_; 47 | 48 | // No copying 49 | Mutex(const Mutex&); 50 | void operator=(const Mutex&); 51 | }; 52 | 53 | class CondVar { 54 | public: 55 | explicit CondVar(Mutex* mu); 56 | ~CondVar(); 57 | void Wait(); 58 | void Signal(); 59 | void SignalAll(); 60 | private: 61 | pthread_cond_t cv_; 62 | Mutex* mu_; 63 | }; 64 | 65 | // Storage for a lock-free pointer 66 | class AtomicPointer { 67 | private: 68 | typedef base::subtle::AtomicWord Rep; 69 | Rep rep_; 70 | public: 71 | AtomicPointer() { } 72 | explicit AtomicPointer(void* p) : rep_(reinterpret_cast(p)) {} 73 | inline void* Acquire_Load() const { 74 | return reinterpret_cast(::base::subtle::Acquire_Load(&rep_)); 75 | } 76 | inline void Release_Store(void* v) { 77 | ::base::subtle::Release_Store(&rep_, reinterpret_cast(v)); 78 | } 79 | inline void* NoBarrier_Load() const { 80 | return reinterpret_cast(::base::subtle::NoBarrier_Load(&rep_)); 81 | } 82 | inline void NoBarrier_Store(void* v) { 83 | ::base::subtle::NoBarrier_Store(&rep_, reinterpret_cast(v)); 84 | } 85 | }; 86 | 87 | // TODO(gabor): Implement actual compress 88 | inline bool Snappy_Compress(const char* input, size_t input_length, 89 | std::string* output) { 90 | return false; 91 | } 92 | 93 | // TODO(gabor): Implement actual uncompress 94 | inline bool Snappy_Uncompress(const char* input_data, size_t input_length, 95 | std::string* output) { 96 | return false; 97 | } 98 | 99 | inline bool GetHeapProfile(void (*func)(void*, const char*, int), void* arg) { 100 | return false; 101 | } 102 | 103 | } 104 | } 105 | 106 | #endif // STORAGE_LEVELDB_PORT_PORT_STD_H_ 107 | -------------------------------------------------------------------------------- /deps/leveldb/doc/log_format.txt: -------------------------------------------------------------------------------- 1 | The log file contents are a sequence of 32KB blocks. The only 2 | exception is that the tail of the file may contain a partial block. 3 | 4 | Each block consists of a sequence of records: 5 | block := record* trailer? 6 | record := 7 | checksum: uint32 // crc32c of type and data[] 8 | length: uint16 9 | type: uint8 // One of FULL, FIRST, MIDDLE, LAST 10 | data: uint8[length] 11 | 12 | A record never starts within the last six bytes of a block (since it 13 | won't fit). Any leftover bytes here form the trailer, which must 14 | consist entirely of zero bytes and must be skipped by readers. 15 | 16 | Aside: if exactly seven bytes are left in the current block, and a new 17 | non-zero length record is added, the writer must emit a FIRST record 18 | (which contains zero bytes of user data) to fill up the trailing seven 19 | bytes of the block and then emit all of the user data in subsequent 20 | blocks. 21 | 22 | More types may be added in the future. Some Readers may skip record 23 | types they do not understand, others may report that some data was 24 | skipped. 25 | 26 | FULL == 1 27 | FIRST == 2 28 | MIDDLE == 3 29 | LAST == 4 30 | 31 | The FULL record contains the contents of an entire user record. 32 | 33 | FIRST, MIDDLE, LAST are types used for user records that have been 34 | split into multiple fragments (typically because of block boundaries). 35 | FIRST is the type of the first fragment of a user record, LAST is the 36 | type of the last fragment of a user record, and MID is the type of all 37 | interior fragments of a user record. 38 | 39 | Example: consider a sequence of user records: 40 | A: length 1000 41 | B: length 97270 42 | C: length 8000 43 | A will be stored as a FULL record in the first block. 44 | 45 | B will be split into three fragments: first fragment occupies the rest 46 | of the first block, second fragment occupies the entirety of the 47 | second block, and the third fragment occupies a prefix of the third 48 | block. This will leave six bytes free in the third block, which will 49 | be left empty as the trailer. 50 | 51 | C will be stored as a FULL record in the fourth block. 52 | 53 | =================== 54 | 55 | Some benefits over the recordio format: 56 | 57 | (1) We do not need any heuristics for resyncing - just go to next 58 | block boundary and scan. If there is a corruption, skip to the next 59 | block. As a side-benefit, we do not get confused when part of the 60 | contents of one log file are embedded as a record inside another log 61 | file. 62 | 63 | (2) Splitting at approximate boundaries (e.g., for mapreduce) is 64 | simple: find the next block boundary and skip records until we 65 | hit a FULL or FIRST record. 66 | 67 | (3) We do not need extra buffering for large records. 68 | 69 | Some downsides compared to recordio format: 70 | 71 | (1) No packing of tiny records. This could be fixed by adding a new 72 | record type, so it is a shortcoming of the current implementation, 73 | not necessarily the format. 74 | 75 | (2) No compression. Again, this could be fixed by adding new record types. 76 | -------------------------------------------------------------------------------- /deps/leveldb/db/filename.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | // 5 | // File names used by DB code 6 | 7 | #ifndef STORAGE_LEVELDB_DB_FILENAME_H_ 8 | #define STORAGE_LEVELDB_DB_FILENAME_H_ 9 | 10 | #include 11 | #include 12 | #include "leveldb/slice.h" 13 | #include "leveldb/status.h" 14 | #include "port/port.h" 15 | 16 | namespace leveldb { 17 | 18 | class Env; 19 | 20 | enum FileType { 21 | kLogFile, 22 | kDBLockFile, 23 | kTableFile, 24 | kDescriptorFile, 25 | kCurrentFile, 26 | kTempFile, 27 | kInfoLogFile, // Either the current one, or an old one 28 | }; 29 | 30 | // Return the name of the log file with the specified number 31 | // in the db named by "dbname". The result will be prefixed with 32 | // "dbname". 33 | extern std::string LogFileName(const std::string& dbname, uint64_t number); 34 | 35 | // Return the name of the sstable with the specified number 36 | // in the db named by "dbname". The result will be prefixed with 37 | // "dbname". 38 | extern std::string TableFileName(const std::string& dbname, uint64_t number); 39 | 40 | // Return the name of the descriptor file for the db named by 41 | // "dbname" and the specified incarnation number. The result will be 42 | // prefixed with "dbname". 43 | extern std::string DescriptorFileName(const std::string& dbname, 44 | uint64_t number); 45 | 46 | // Return the name of the current file. This file contains the name 47 | // of the current manifest file. The result will be prefixed with 48 | // "dbname". 49 | extern std::string CurrentFileName(const std::string& dbname); 50 | 51 | // Return the name of the lock file for the db named by 52 | // "dbname". The result will be prefixed with "dbname". 53 | extern std::string LockFileName(const std::string& dbname); 54 | 55 | // Return the name of a temporary file owned by the db named "dbname". 56 | // The result will be prefixed with "dbname". 57 | extern std::string TempFileName(const std::string& dbname, uint64_t number); 58 | 59 | // Return the name of the info log file for "dbname". 60 | extern std::string InfoLogFileName(const std::string& dbname); 61 | 62 | // Return the name of the old info log file for "dbname". 63 | extern std::string OldInfoLogFileName(const std::string& dbname); 64 | 65 | // If filename is a leveldb file, store the type of the file in *type. 66 | // The number encoded in the filename is stored in *number. If the 67 | // filename was successfully parsed, returns true. Else return false. 68 | extern bool ParseFileName(const std::string& filename, 69 | uint64_t* number, 70 | FileType* type); 71 | 72 | // Make the CURRENT file point to the descriptor file with the 73 | // specified number. 74 | extern Status SetCurrentFile(Env* env, const std::string& dbname, 75 | uint64_t descriptor_number); 76 | 77 | 78 | } 79 | 80 | #endif // STORAGE_LEVELDB_DB_FILENAME_H_ 81 | -------------------------------------------------------------------------------- /deps/leveldb/db/dbformat.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include 6 | #include "db/dbformat.h" 7 | #include "port/port.h" 8 | #include "util/coding.h" 9 | 10 | namespace leveldb { 11 | 12 | static uint64_t PackSequenceAndType(uint64_t seq, ValueType t) { 13 | assert(seq <= kMaxSequenceNumber); 14 | assert(t <= kValueTypeForSeek); 15 | return (seq << 8) | t; 16 | } 17 | 18 | void AppendInternalKey(std::string* result, const ParsedInternalKey& key) { 19 | result->append(key.user_key.data(), key.user_key.size()); 20 | PutFixed64(result, PackSequenceAndType(key.sequence, key.type)); 21 | } 22 | 23 | std::string ParsedInternalKey::DebugString() const { 24 | char buf[50]; 25 | snprintf(buf, sizeof(buf), "' @ %llu : %d", 26 | (unsigned long long) sequence, 27 | int(type)); 28 | std::string result = "'"; 29 | result += user_key.ToString(); 30 | result += buf; 31 | return result; 32 | } 33 | 34 | const char* InternalKeyComparator::Name() const { 35 | return "leveldb.InternalKeyComparator"; 36 | } 37 | 38 | int InternalKeyComparator::Compare(const Slice& akey, const Slice& bkey) const { 39 | // Order by: 40 | // increasing user key (according to user-supplied comparator) 41 | // decreasing sequence number 42 | // decreasing type (though sequence# should be enough to disambiguate) 43 | int r = user_comparator_->Compare(ExtractUserKey(akey), ExtractUserKey(bkey)); 44 | if (r == 0) { 45 | const uint64_t anum = DecodeFixed64(akey.data() + akey.size() - 8); 46 | const uint64_t bnum = DecodeFixed64(bkey.data() + bkey.size() - 8); 47 | if (anum > bnum) { 48 | r = -1; 49 | } else if (anum < bnum) { 50 | r = +1; 51 | } 52 | } 53 | return r; 54 | } 55 | 56 | void InternalKeyComparator::FindShortestSeparator( 57 | std::string* start, 58 | const Slice& limit) const { 59 | // Attempt to shorten the user portion of the key 60 | Slice user_start = ExtractUserKey(*start); 61 | Slice user_limit = ExtractUserKey(limit); 62 | std::string tmp(user_start.data(), user_start.size()); 63 | user_comparator_->FindShortestSeparator(&tmp, user_limit); 64 | if (user_comparator_->Compare(*start, tmp) < 0) { 65 | // User key has become larger. Tack on the earliest possible 66 | // number to the shortened user key. 67 | PutFixed64(&tmp, PackSequenceAndType(kMaxSequenceNumber,kValueTypeForSeek)); 68 | assert(this->Compare(*start, tmp) < 0); 69 | assert(this->Compare(tmp, limit) < 0); 70 | start->swap(tmp); 71 | } 72 | } 73 | 74 | void InternalKeyComparator::FindShortSuccessor(std::string* key) const { 75 | Slice user_key = ExtractUserKey(*key); 76 | std::string tmp(user_key.data(), user_key.size()); 77 | user_comparator_->FindShortSuccessor(&tmp); 78 | if (user_comparator_->Compare(user_key, tmp) < 0) { 79 | // User key has become larger. Tack on the earliest possible 80 | // number to the shortened user key. 81 | PutFixed64(&tmp, PackSequenceAndType(kMaxSequenceNumber,kValueTypeForSeek)); 82 | assert(this->Compare(*key, tmp) < 0); 83 | key->swap(tmp); 84 | } 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /deps/leveldb/db/log_writer.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include "db/log_writer.h" 6 | 7 | #include 8 | #include "leveldb/env.h" 9 | #include "util/coding.h" 10 | #include "util/crc32c.h" 11 | 12 | namespace leveldb { 13 | namespace log { 14 | 15 | Writer::Writer(WritableFile* dest) 16 | : dest_(dest), 17 | block_offset_(0) { 18 | for (int i = 0; i <= kMaxRecordType; i++) { 19 | char t = static_cast(i); 20 | type_crc_[i] = crc32c::Value(&t, 1); 21 | } 22 | } 23 | 24 | Writer::~Writer() { 25 | } 26 | 27 | Status Writer::AddRecord(const Slice& slice) { 28 | const char* ptr = slice.data(); 29 | size_t left = slice.size(); 30 | 31 | // Fragment the record if necessary and emit it. Note that if slice 32 | // is empty, we still want to iterate once to emit a single 33 | // zero-length record 34 | Status s; 35 | bool begin = true; 36 | do { 37 | const int leftover = kBlockSize - block_offset_; 38 | assert(leftover >= 0); 39 | if (leftover < kHeaderSize) { 40 | // Switch to a new block 41 | if (leftover > 0) { 42 | // Fill the trailer (literal below relies on kHeaderSize being 7) 43 | assert(kHeaderSize == 7); 44 | dest_->Append(Slice("\x00\x00\x00\x00\x00\x00", leftover)); 45 | } 46 | block_offset_ = 0; 47 | } 48 | 49 | // Invariant: we never leave < kHeaderSize bytes in a block. 50 | assert(kBlockSize - block_offset_ - kHeaderSize >= 0); 51 | 52 | const size_t avail = kBlockSize - block_offset_ - kHeaderSize; 53 | const size_t fragment_length = (left < avail) ? left : avail; 54 | 55 | RecordType type; 56 | const bool end = (left == fragment_length); 57 | if (begin && end) { 58 | type = kFullType; 59 | } else if (begin) { 60 | type = kFirstType; 61 | } else if (end) { 62 | type = kLastType; 63 | } else { 64 | type = kMiddleType; 65 | } 66 | 67 | s = EmitPhysicalRecord(type, ptr, fragment_length); 68 | ptr += fragment_length; 69 | left -= fragment_length; 70 | begin = false; 71 | } while (s.ok() && left > 0); 72 | return s; 73 | } 74 | 75 | Status Writer::EmitPhysicalRecord(RecordType t, const char* ptr, size_t n) { 76 | assert(n <= 0xffff); // Must fit in two bytes 77 | assert(block_offset_ + kHeaderSize + n <= kBlockSize); 78 | 79 | // Format the header 80 | char buf[kHeaderSize]; 81 | buf[4] = static_cast(n & 0xff); 82 | buf[5] = static_cast(n >> 8); 83 | buf[6] = static_cast(t); 84 | 85 | // Compute the crc of the record type and the payload. 86 | uint32_t crc = crc32c::Extend(type_crc_[t], ptr, n); 87 | crc = crc32c::Mask(crc); // Adjust for storage 88 | EncodeFixed32(buf, crc); 89 | 90 | // Write the header and the payload 91 | Status s = dest_->Append(Slice(buf, kHeaderSize)); 92 | if (s.ok()) { 93 | s = dest_->Append(Slice(ptr, n)); 94 | if (s.ok()) { 95 | s = dest_->Flush(); 96 | } 97 | } 98 | block_offset_ += kHeaderSize + n; 99 | return s; 100 | } 101 | 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /deps/leveldb/table/format.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_TABLE_FORMAT_H_ 6 | #define STORAGE_LEVELDB_TABLE_FORMAT_H_ 7 | 8 | #include 9 | #include 10 | #include "leveldb/slice.h" 11 | #include "leveldb/status.h" 12 | #include "leveldb/table_builder.h" 13 | 14 | namespace leveldb { 15 | 16 | class Block; 17 | class RandomAccessFile; 18 | struct ReadOptions; 19 | 20 | // BlockHandle is a pointer to the extent of a file that stores a data 21 | // block or a meta block. 22 | class BlockHandle { 23 | public: 24 | BlockHandle(); 25 | 26 | // The offset of the block in the file. 27 | uint64_t offset() const { return offset_; } 28 | void set_offset(uint64_t offset) { offset_ = offset; } 29 | 30 | // The size of the stored block 31 | uint64_t size() const { return size_; } 32 | void set_size(uint64_t size) { size_ = size; } 33 | 34 | void EncodeTo(std::string* dst) const; 35 | Status DecodeFrom(Slice* input); 36 | 37 | // Maximum encoding length of a BlockHandle 38 | enum { kMaxEncodedLength = 10 + 10 }; 39 | 40 | private: 41 | uint64_t offset_; 42 | uint64_t size_; 43 | }; 44 | 45 | // Footer encapsulates the fixed information stored at the tail 46 | // end of every table file. 47 | class Footer { 48 | public: 49 | Footer() { } 50 | 51 | // The block handle for the metaindex block of the table 52 | const BlockHandle& metaindex_handle() const { return metaindex_handle_; } 53 | void set_metaindex_handle(const BlockHandle& h) { metaindex_handle_ = h; } 54 | 55 | // The block handle for the index block of the table 56 | const BlockHandle& index_handle() const { 57 | return index_handle_; 58 | } 59 | void set_index_handle(const BlockHandle& h) { 60 | index_handle_ = h; 61 | } 62 | 63 | void EncodeTo(std::string* dst) const; 64 | Status DecodeFrom(Slice* input); 65 | 66 | // Encoded length of a Footer. Note that the serialization of a 67 | // Footer will always occupy exactly this many bytes. It consists 68 | // of two block handles and a magic number. 69 | enum { 70 | kEncodedLength = 2*BlockHandle::kMaxEncodedLength + 8 71 | }; 72 | 73 | private: 74 | BlockHandle metaindex_handle_; 75 | BlockHandle index_handle_; 76 | }; 77 | 78 | // kTableMagicNumber was picked by running 79 | // echo http://code.google.com/p/leveldb/ | sha1sum 80 | // and taking the leading 64 bits. 81 | static const uint64_t kTableMagicNumber = 0xdb4775248b80fb57ull; 82 | 83 | // 1-byte type + 32-bit crc 84 | static const size_t kBlockTrailerSize = 5; 85 | 86 | // Read the block identified by "handle" from "file". On success, 87 | // store a pointer to the heap-allocated result in *block and return 88 | // OK. On failure store NULL in *block and return non-OK. 89 | extern Status ReadBlock(RandomAccessFile* file, 90 | const ReadOptions& options, 91 | const BlockHandle& handle, 92 | Block** block); 93 | 94 | // Implementation details follow. Clients should ignore, 95 | 96 | inline BlockHandle::BlockHandle() 97 | : offset_(~static_cast(0)), 98 | size_(~static_cast(0)) { 99 | } 100 | 101 | } 102 | 103 | #endif // STORAGE_LEVELDB_TABLE_FORMAT_H_ 104 | -------------------------------------------------------------------------------- /deps/leveldb/db/version_edit.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_DB_VERSION_EDIT_H_ 6 | #define STORAGE_LEVELDB_DB_VERSION_EDIT_H_ 7 | 8 | #include 9 | #include 10 | #include 11 | #include "db/dbformat.h" 12 | 13 | namespace leveldb { 14 | 15 | class VersionSet; 16 | 17 | struct FileMetaData { 18 | int refs; 19 | uint64_t number; 20 | uint64_t file_size; // File size in bytes 21 | InternalKey smallest; // Smallest internal key served by table 22 | InternalKey largest; // Largest internal key served by table 23 | 24 | FileMetaData() : refs(0), file_size(0) { } 25 | }; 26 | 27 | class VersionEdit { 28 | public: 29 | VersionEdit() { Clear(); } 30 | ~VersionEdit() { } 31 | 32 | void Clear(); 33 | 34 | void SetComparatorName(const Slice& name) { 35 | has_comparator_ = true; 36 | comparator_ = name.ToString(); 37 | } 38 | void SetLogNumber(uint64_t num) { 39 | has_log_number_ = true; 40 | log_number_ = num; 41 | } 42 | void SetPrevLogNumber(uint64_t num) { 43 | has_prev_log_number_ = true; 44 | prev_log_number_ = num; 45 | } 46 | void SetNextFile(uint64_t num) { 47 | has_next_file_number_ = true; 48 | next_file_number_ = num; 49 | } 50 | void SetLastSequence(SequenceNumber seq) { 51 | has_last_sequence_ = true; 52 | last_sequence_ = seq; 53 | } 54 | void SetCompactPointer(int level, const InternalKey& key) { 55 | compact_pointers_.push_back(std::make_pair(level, key)); 56 | } 57 | 58 | // Add the specified file at the specified number. 59 | // REQUIRES: This version has not been saved (see VersionSet::SaveTo) 60 | // REQUIRES: "smallest" and "largest" are smallest and largest keys in file 61 | void AddFile(int level, uint64_t file, 62 | uint64_t file_size, 63 | const InternalKey& smallest, 64 | const InternalKey& largest) { 65 | FileMetaData f; 66 | f.number = file; 67 | f.file_size = file_size; 68 | f.smallest = smallest; 69 | f.largest = largest; 70 | new_files_.push_back(std::make_pair(level, f)); 71 | } 72 | 73 | // Delete the specified "file" from the specified "level". 74 | void DeleteFile(int level, uint64_t file) { 75 | deleted_files_.insert(std::make_pair(level, file)); 76 | } 77 | 78 | void EncodeTo(std::string* dst) const; 79 | Status DecodeFrom(const Slice& src); 80 | 81 | std::string DebugString() const; 82 | 83 | private: 84 | friend class VersionSet; 85 | 86 | USED_BY_NESTED_FRIEND2(typedef std::set< std::pair > DeletedFileSet) 87 | 88 | std::string comparator_; 89 | uint64_t log_number_; 90 | uint64_t prev_log_number_; 91 | uint64_t next_file_number_; 92 | SequenceNumber last_sequence_; 93 | bool has_comparator_; 94 | bool has_log_number_; 95 | bool has_prev_log_number_; 96 | bool has_next_file_number_; 97 | bool has_last_sequence_; 98 | 99 | USED_BY_NESTED_FRIEND2(std::vector< std::pair > compact_pointers_) 100 | USED_BY_NESTED_FRIEND(DeletedFileSet deleted_files_) 101 | USED_BY_NESTED_FRIEND2(std::vector< std::pair > new_files_) 102 | }; 103 | 104 | } 105 | 106 | #endif // STORAGE_LEVELDB_DB_VERSION_EDIT_H_ 107 | -------------------------------------------------------------------------------- /src/DB.h: -------------------------------------------------------------------------------- 1 | #ifndef DB_H_ 2 | #define DB_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "leveldb/db.h" 8 | #include "WriteBatch.h" 9 | 10 | using namespace v8; 11 | using namespace node; 12 | 13 | namespace node_leveldb { 14 | 15 | class DB : ObjectWrap { 16 | public: 17 | DB(); 18 | virtual ~DB(); 19 | 20 | static void Init(Handle target); 21 | 22 | private: 23 | static Handle New(const Arguments& args); 24 | 25 | static Handle Open(const Arguments& args); 26 | static Handle Close(const Arguments& args); 27 | 28 | static Handle Put(const Arguments& args); 29 | static Handle Del(const Arguments& args); 30 | static Handle Write(const Arguments& args); 31 | 32 | static Handle Get(const Arguments& args); 33 | 34 | static Handle NewIterator(const Arguments& args); 35 | 36 | static Handle GetSnapshot(const Arguments& args); 37 | static Handle ReleaseSnapshot(const Arguments& args); 38 | 39 | static Handle GetProperty(const Arguments& args); 40 | static Handle GetApproximateSizes(const Arguments& args); 41 | 42 | static Handle DestroyDB(const Arguments& args); 43 | static Handle RepairDB(const Arguments& args); 44 | 45 | 46 | struct Params { 47 | Params(DB* self, Handle cb); 48 | virtual ~Params(); 49 | virtual void Callback(Handle result = Handle()); 50 | 51 | DB* self; 52 | Persistent callback; 53 | leveldb::Status status; 54 | }; 55 | 56 | struct OpenParams : Params { 57 | OpenParams(DB *self, std::string name, leveldb::Options &options, Handle callback) 58 | : Params(self, callback), name(name), options(options) {} 59 | 60 | std::string name; 61 | leveldb::Options options; 62 | }; 63 | 64 | struct ReadParams : Params { 65 | ReadParams(DB *self, leveldb::Slice key, leveldb::ReadOptions &options, Handle callback, std::vector *strings = NULL) 66 | : Params(self, callback), key(key), options(options), strings(strings) {} 67 | 68 | virtual ~ReadParams(); 69 | 70 | leveldb::Slice key; 71 | leveldb::ReadOptions options; 72 | std::vector *strings; 73 | std::string result; 74 | }; 75 | 76 | struct WriteParams : Params { 77 | WriteParams(DB *self, WriteBatch *writeBatch, leveldb::WriteOptions &options, Handle callback) 78 | : Params(self, callback), writeBatch(writeBatch), options(options), disposeWriteBatch(false) {} 79 | 80 | WriteBatch *writeBatch; 81 | leveldb::WriteOptions options; 82 | bool disposeWriteBatch; // when set, EIO_AfterWrite will delete the writeBatch 83 | }; 84 | 85 | static void EIO_BeforeOpen(OpenParams *params); 86 | static int EIO_Open(eio_req *req); 87 | static int EIO_AfterOpen(eio_req *req); 88 | 89 | static void EIO_BeforeClose(Params *params); 90 | static int EIO_Close(eio_req *req); 91 | static int EIO_AfterClose(eio_req *req); 92 | 93 | static void EIO_BeforeRead(ReadParams *params); 94 | static int EIO_Read(eio_req *req); 95 | static int EIO_AfterRead(eio_req *req); 96 | 97 | static void EIO_BeforeWrite(WriteParams *params); 98 | static int EIO_Write(eio_req *req); 99 | static int EIO_AfterWrite(eio_req *req); 100 | 101 | leveldb::DB* db; 102 | static Persistent persistent_function_template; 103 | }; 104 | 105 | } // node_leveldb 106 | 107 | #endif // DB_H_ 108 | -------------------------------------------------------------------------------- /deps/leveldb/include/leveldb/status.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | // 5 | // A Status encapsulates the result of an operation. It may indicate success, 6 | // or it may indicate an error with an associated error message. 7 | // 8 | // Multiple threads can invoke const methods on a Status without 9 | // external synchronization, but if any of the threads may call a 10 | // non-const method, all threads accessing the same Status must use 11 | // external synchronization. 12 | 13 | #ifndef STORAGE_LEVELDB_INCLUDE_STATUS_H_ 14 | #define STORAGE_LEVELDB_INCLUDE_STATUS_H_ 15 | 16 | #include 17 | #include "leveldb/slice.h" 18 | 19 | namespace leveldb { 20 | 21 | class Status { 22 | public: 23 | // Create a success status. 24 | Status() : state_(NULL) { } 25 | ~Status() { delete[] state_; } 26 | 27 | // Copy the specified status. 28 | Status(const Status& s); 29 | void operator=(const Status& s); 30 | 31 | // Return a success status. 32 | static Status OK() { return Status(); } 33 | 34 | // Return error status of an appropriate type. 35 | static Status NotFound(const Slice& msg, const Slice& msg2 = Slice()) { 36 | return Status(kNotFound, msg, msg2); 37 | } 38 | static Status Corruption(const Slice& msg, const Slice& msg2 = Slice()) { 39 | return Status(kCorruption, msg, msg2); 40 | } 41 | static Status NotSupported(const Slice& msg, const Slice& msg2 = Slice()) { 42 | return Status(kNotSupported, msg, msg2); 43 | } 44 | static Status InvalidArgument(const Slice& msg, const Slice& msg2 = Slice()) { 45 | return Status(kInvalidArgument, msg, msg2); 46 | } 47 | static Status IOError(const Slice& msg, const Slice& msg2 = Slice()) { 48 | return Status(kIOError, msg, msg2); 49 | } 50 | 51 | // Returns true iff the status indicates success. 52 | bool ok() const { return (state_ == NULL); } 53 | 54 | // Returns true iff the status indicates a NotFound error. 55 | bool IsNotFound() const { return code() == kNotFound; } 56 | 57 | // Return a string representation of this status suitable for printing. 58 | // Returns the string "OK" for success. 59 | std::string ToString() const; 60 | 61 | private: 62 | // OK status has a NULL state_. Otherwise, state_ is a new[] array 63 | // of the following form: 64 | // state_[0..3] == length of message 65 | // state_[4] == code 66 | // state_[5..] == message 67 | const char* state_; 68 | 69 | enum Code { 70 | kOk = 0, 71 | kNotFound = 1, 72 | kCorruption = 2, 73 | kNotSupported = 3, 74 | kInvalidArgument = 4, 75 | kIOError = 5, 76 | }; 77 | 78 | Code code() const { 79 | return (state_ == NULL) ? kOk : static_cast(state_[4]); 80 | } 81 | 82 | Status(Code code, const Slice& msg, const Slice& msg2); 83 | static const char* CopyState(const char* s); 84 | }; 85 | 86 | inline Status::Status(const Status& s) { 87 | state_ = (s.state_ == NULL) ? NULL : CopyState(s.state_); 88 | } 89 | inline void Status::operator=(const Status& s) { 90 | // The following condition catches both aliasing (when this == &s), 91 | // and the common case where both s and *this are ok. 92 | if (state_ != s.state_) { 93 | delete[] state_; 94 | state_ = (s.state_ == NULL) ? NULL : CopyState(s.state_); 95 | } 96 | } 97 | 98 | } 99 | 100 | #endif // STORAGE_LEVELDB_INCLUDE_STATUS_H_ 101 | -------------------------------------------------------------------------------- /deps/leveldb/include/leveldb/table_builder.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | // 5 | // TableBuilder provides the interface used to build a Table 6 | // (an immutable and sorted map from keys to values). 7 | // 8 | // Multiple threads can invoke const methods on a TableBuilder without 9 | // external synchronization, but if any of the threads may call a 10 | // non-const method, all threads accessing the same TableBuilder must use 11 | // external synchronization. 12 | 13 | #ifndef STORAGE_LEVELDB_INCLUDE_TABLE_BUILDER_H_ 14 | #define STORAGE_LEVELDB_INCLUDE_TABLE_BUILDER_H_ 15 | 16 | #include 17 | #include "leveldb/options.h" 18 | #include "leveldb/status.h" 19 | 20 | namespace leveldb { 21 | 22 | class BlockBuilder; 23 | class BlockHandle; 24 | class WritableFile; 25 | 26 | class TableBuilder { 27 | public: 28 | // Create a builder that will store the contents of the table it is 29 | // building in *file. Does not close the file. It is up to the 30 | // caller to close the file after calling Finish(). 31 | TableBuilder(const Options& options, WritableFile* file); 32 | 33 | // REQUIRES: Either Finish() or Abandon() has been called. 34 | ~TableBuilder(); 35 | 36 | // Change the options used by this builder. Note: only some of the 37 | // option fields can be changed after construction. If a field is 38 | // not allowed to change dynamically and its value in the structure 39 | // passed to the constructor is different from its value in the 40 | // structure passed to this method, this method will return an error 41 | // without changing any fields. 42 | Status ChangeOptions(const Options& options); 43 | 44 | // Add key,value to the table being constructed. 45 | // REQUIRES: key is after any previously added key according to comparator. 46 | // REQUIRES: Finish(), Abandon() have not been called 47 | void Add(const Slice& key, const Slice& value); 48 | 49 | // Advanced operation: flush any buffered key/value pairs to file. 50 | // Can be used to ensure that two adjacent entries never live in 51 | // the same data block. Most clients should not need to use this method. 52 | // REQUIRES: Finish(), Abandon() have not been called 53 | void Flush(); 54 | 55 | // Return non-ok iff some error has been detected. 56 | Status status() const; 57 | 58 | // Finish building the table. Stops using the file passed to the 59 | // constructor after this function returns. 60 | // REQUIRES: Finish(), Abandon() have not been called 61 | Status Finish(); 62 | 63 | // Indicate that the contents of this builder should be abandoned. Stops 64 | // using the file passed to the constructor after this function returns. 65 | // If the caller is not going to call Finish(), it must call Abandon() 66 | // before destroying this builder. 67 | // REQUIRES: Finish(), Abandon() have not been called 68 | void Abandon(); 69 | 70 | // Number of calls to Add() so far. 71 | uint64_t NumEntries() const; 72 | 73 | // Size of the file generated so far. If invoked after a successful 74 | // Finish() call, returns the size of the final generated file. 75 | uint64_t FileSize() const; 76 | 77 | private: 78 | bool ok() const { return status().ok(); } 79 | void WriteBlock(BlockBuilder* block, BlockHandle* handle); 80 | 81 | struct Rep; 82 | Rep* rep_; 83 | 84 | // No copying allowed 85 | TableBuilder(const TableBuilder&); 86 | void operator=(const TableBuilder&); 87 | }; 88 | 89 | } 90 | 91 | #endif // STORAGE_LEVELDB_INCLUDE_TABLE_BUILDER_H_ 92 | -------------------------------------------------------------------------------- /deps/leveldb/include/leveldb/slice.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | // 5 | // Slice is a simple structure containing a pointer into some external 6 | // storage and a size. The user of a Slice must ensure that the slice 7 | // is not used after the corresponding external storage has been 8 | // deallocated. 9 | // 10 | // Multiple threads can invoke const methods on a Slice without 11 | // external synchronization, but if any of the threads may call a 12 | // non-const method, all threads accessing the same Slice must use 13 | // external synchronization. 14 | 15 | #ifndef STORAGE_LEVELDB_INCLUDE_SLICE_H_ 16 | #define STORAGE_LEVELDB_INCLUDE_SLICE_H_ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | namespace leveldb { 24 | 25 | class Slice { 26 | public: 27 | // Create an empty slice. 28 | Slice() : data_(""), size_(0) { } 29 | 30 | // Create a slice that refers to data[0,n-1]. 31 | Slice(const char* data, size_t n) : data_(data), size_(n) { } 32 | 33 | // Create a slice that refers to the contents of "s" 34 | Slice(const std::string& s) : data_(s.data()), size_(s.size()) { } 35 | 36 | // Create a slice that refers to s[0,strlen(s)-1] 37 | Slice(const char* s) : data_(s), size_(strlen(s)) { } 38 | 39 | // Return a pointer to the beginning of the referenced data 40 | const char* data() const { return data_; } 41 | 42 | // Return the length (in bytes) of the referenced data 43 | size_t size() const { return size_; } 44 | 45 | // Return true iff the length of the referenced data is zero 46 | bool empty() const { return size_ == 0; } 47 | 48 | // Return the ith byte in the referenced data. 49 | // REQUIRES: n < size() 50 | char operator[](size_t n) const { 51 | assert(n < size()); 52 | return data_[n]; 53 | } 54 | 55 | // Change this slice to refer to an empty array 56 | void clear() { data_ = ""; size_ = 0; } 57 | 58 | // Drop the first "n" bytes from this slice. 59 | void remove_prefix(size_t n) { 60 | assert(n <= size()); 61 | data_ += n; 62 | size_ -= n; 63 | } 64 | 65 | // Return a string that contains the copy of the referenced data. 66 | std::string ToString() const { return std::string(data_, size_); } 67 | 68 | // Three-way comparison. Returns value: 69 | // < 0 iff "*this" < "b", 70 | // == 0 iff "*this" == "b", 71 | // > 0 iff "*this" > "b" 72 | int compare(const Slice& b) const; 73 | 74 | // Return true iff "x" is a prefix of "*this" 75 | bool starts_with(const Slice& x) const { 76 | return ((size_ >= x.size_) && 77 | (memcmp(data_, x.data_, x.size_) == 0)); 78 | } 79 | 80 | private: 81 | const char* data_; 82 | size_t size_; 83 | 84 | // Intentionally copyable 85 | }; 86 | 87 | inline bool operator==(const Slice& x, const Slice& y) { 88 | return ((x.size() == y.size()) && 89 | (memcmp(x.data(), y.data(), x.size()) == 0)); 90 | } 91 | 92 | inline bool operator!=(const Slice& x, const Slice& y) { 93 | return !(x == y); 94 | } 95 | 96 | inline int Slice::compare(const Slice& b) const { 97 | const int min_len = (size_ < b.size_) ? size_ : b.size_; 98 | int r = memcmp(data_, b.data_, min_len); 99 | if (r == 0) { 100 | if (size_ < b.size_) r = -1; 101 | else if (size_ > b.size_) r = +1; 102 | } 103 | return r; 104 | } 105 | 106 | } 107 | 108 | 109 | #endif // STORAGE_LEVELDB_INCLUDE_SLICE_H_ 110 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | # Node-LevelDB 2 | 3 | The leveldb library provides a persistent key value store. Keys and values are arbitrary byte arrays. The keys are ordered within the key value store according to a user-specified comparator function. 4 | 5 | This project is node bindings to this excellent library so that node programs can either implement their own custom databases or simply use it directly as a fast, simple key/value store. 6 | 7 | While implementing nStore, I realized there are a couple things that V8 and node are not very good at. They are heavy disk I/O and massive objects with either millions of keys or millions of sub objects. 8 | 9 | Since LevelDB provides good primitives like MVCC and binary support (It was designed to back IndexDB in the Chrome browser), then it can be used as a base to implement things like CouchDB. 10 | 11 | ## TODO 12 | 13 | 1. Trun Iterator code to be async 14 | 15 | ## Status 16 | 17 | This project is still under heavy development in my free-time. It was started by a long night where I couldn't sleep. I am not a C++ coder and am learning as I go. 18 | 19 | The I/O in this initial version is all blocking and doesn't make use of node's thread pool for disk I/O. Since my use case is single-user applications, this is a perfectly fine compromise. 20 | 21 | Eventually I'll need to make async versions of all the calls so that it can also be used in a highly concurrent server environment. 22 | 23 | ## API 24 | 25 | The API is meant to be an almost one-to-one mapping to the underlying C++ library. Essentially it's a key/value store, but has some extra nice things like sorted keys, snapshots and iterators. 26 | 27 | ### LevelDB 28 | 29 | This is the main Class and probably the only one that a user needs to create manually. 30 | 31 | var DB = require('leveldb.node').DB; 32 | var db = new DB; 33 | db.open({create_if_missing: true}, "path/to/my/db"); 34 | var key = new Buffer("myKey"); 35 | db.put({}, key, new Buffer("My Value!")); 36 | var value = db.get({}, key); 37 | console.dir(value); 38 | db.del({}, key); 39 | db.close(); 40 | 41 | I'll document more as this stabilizes. In the mean-time, check out the demo scripts I use for testing. 42 | 43 | 44 | ## Compiling 45 | 46 | I've only tested on my Ubuntu laptop, but it compiles cleanly using only the wscript file. To compile simple type. 47 | 48 | node-waf configure build 49 | 50 | Then to test, run the demo script 51 | 52 | node demo/demo.js 53 | 54 | The leveldb library is bundled in the deps folder and is compiled in staticly. The resulting node addon is about 4mb unstripped. If you want to make it smaller, I've had success using the `strip` command on it which shrinks it down to about 300kb. 55 | 56 | strip build/default/leveldb.node 57 | 58 | ## Contributing 59 | 60 | Since I am not experienced in the world of C++ and am still learning, I welcome contributions. Mainly what I need right now is someone with experience to review my code and tell me things I'm doing stupid. Maybe add a C++ best pratices note to this document. Also once the initial blocking version of the library is done, I'll need to add async ability to all the functions that do disk I/O. 61 | 62 | Currently Randall Leeds (@tilgovi and one of the CouchDB commiters) has expressed interest in helping and already has commit rights to the project. 63 | 64 | ## Roadmap 65 | 66 | This is the short-term and long roadmap to track progress. 67 | 68 | - Implement just enough to make a simple key/value store. (100% done) 69 | - Implement bulk writes 70 | - Implement Iterators 71 | - Implement Snapstops 72 | - Implement getProperty and getApproximateSizes 73 | - ... 74 | - Add async versions of all functions that use disk I/O 75 | - ... 76 | - Hand off project to a loyal maintainer and start my next adventure. 77 | 78 | -------------------------------------------------------------------------------- /src/helpers.cc: -------------------------------------------------------------------------------- 1 | #include "helpers.h" 2 | 3 | namespace node_leveldb { 4 | 5 | leveldb::Options JsToOptions(Handle val) { 6 | HandleScope scope; 7 | Local obj = Object::Cast(*val); 8 | leveldb::Options options; 9 | if (obj->Has(String::New("create_if_missing"))) { 10 | options.create_if_missing = obj->Get(String::New("create_if_missing"))->BooleanValue(); 11 | } 12 | if (obj->Has(String::New("error_if_exists"))) { 13 | options.error_if_exists = obj->Get(String::New("error_if_exists"))->BooleanValue(); 14 | } 15 | if (obj->Has(String::New("paranoid_checks"))) { 16 | options.paranoid_checks = obj->Get(String::New("paranoid_checks"))->BooleanValue(); 17 | } 18 | if (obj->Has(String::New("write_buffer_size"))) { 19 | options.write_buffer_size = obj->Get(String::New("write_buffer_size"))->Int32Value(); 20 | } 21 | if (obj->Has(String::New("max_open_files"))) { 22 | options.max_open_files = obj->Get(String::New("max_open_files"))->Int32Value(); 23 | } 24 | if (obj->Has(String::New("block_size"))) { 25 | options.block_size = obj->Get(String::New("block_size"))->Int32Value(); 26 | } 27 | if (obj->Has(String::New("block_restart_interval"))) { 28 | options.block_restart_interval = obj->Get(String::New("block_restart_interval"))->Int32Value(); 29 | } 30 | return options; 31 | } 32 | 33 | leveldb::ReadOptions JsToReadOptions(Handle val) { 34 | HandleScope scope; 35 | leveldb::ReadOptions options; 36 | Local obj = Object::Cast(*val); 37 | if (obj->Has(String::New("verify_checksums"))) { 38 | options.verify_checksums = obj->Get(String::New("verify_checksums"))->BooleanValue(); 39 | } 40 | if (obj->Has(String::New("fill_cache"))) { 41 | options.fill_cache = obj->Get(String::New("fill_cache"))->BooleanValue(); 42 | } 43 | return options; 44 | } 45 | 46 | leveldb::WriteOptions JsToWriteOptions(Handle val) { 47 | HandleScope scope; 48 | leveldb::WriteOptions options; 49 | Local obj = Object::Cast(*val); 50 | if (obj->Has(String::New("sync"))) { 51 | options.sync = obj->Get(String::New("sync"))->BooleanValue(); 52 | } 53 | return options; 54 | } 55 | 56 | leveldb::Slice JsToSlice(Handle val, std::vector *strings) { 57 | HandleScope scope; 58 | if (val->IsString() && strings != NULL) { 59 | std::string str(*String::Utf8Value(val)); 60 | strings->push_back(str); 61 | return leveldb::Slice(str.data(), str.length()); 62 | } 63 | else if (Buffer::HasInstance(val)) { 64 | Local obj = Object::Cast(*val); 65 | return leveldb::Slice(BufferData(obj), BufferLength(obj)); 66 | } 67 | else { 68 | return leveldb::Slice(); 69 | } 70 | } 71 | 72 | Handle processStatus(leveldb::Status status) { 73 | if (status.ok()) return String::New(status.ToString().c_str()); 74 | return ThrowException(Exception::Error(String::New(status.ToString().c_str()))); 75 | } 76 | 77 | Local Bufferize(std::string value) { 78 | int length = value.length(); 79 | Buffer *slowBuffer = Buffer::New(length); 80 | memcpy(BufferData(slowBuffer), value.c_str(), length); 81 | Local bufferConstructor = Local::Cast(Context::GetCurrent()->Global()->Get(String::New("Buffer"))); 82 | Handle constructorArgs[3] = { slowBuffer->handle_, Integer::New(length), Integer::New(0) }; 83 | 84 | return bufferConstructor->NewInstance(3, constructorArgs); 85 | } 86 | 87 | char* BufferData(Buffer *b) { 88 | return Buffer::Data(b->handle_); 89 | } 90 | 91 | size_t BufferLength(Buffer *b) { 92 | return Buffer::Length(b->handle_); 93 | } 94 | 95 | char* BufferData(Handle buf_obj) { 96 | return Buffer::Data(buf_obj); 97 | } 98 | 99 | size_t BufferLength(Handle buf_obj) { 100 | return Buffer::Length(buf_obj); 101 | } 102 | 103 | } // node_leveldb 104 | -------------------------------------------------------------------------------- /deps/leveldb/db/filename_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include "db/filename.h" 6 | 7 | #include "db/dbformat.h" 8 | #include "port/port.h" 9 | #include "util/logging.h" 10 | #include "util/testharness.h" 11 | 12 | namespace leveldb { 13 | 14 | class FileNameTest { }; 15 | 16 | TEST(FileNameTest, Parse) { 17 | Slice db; 18 | FileType type; 19 | uint64_t number; 20 | 21 | // Successful parses 22 | static struct { 23 | const char* fname; 24 | uint64_t number; 25 | FileType type; 26 | } cases[] = { 27 | { "100.log", 100, kLogFile }, 28 | { "0.log", 0, kLogFile }, 29 | { "0.sst", 0, kTableFile }, 30 | { "CURRENT", 0, kCurrentFile }, 31 | { "LOCK", 0, kDBLockFile }, 32 | { "MANIFEST-2", 2, kDescriptorFile }, 33 | { "MANIFEST-7", 7, kDescriptorFile }, 34 | { "LOG", 0, kInfoLogFile }, 35 | { "LOG.old", 0, kInfoLogFile }, 36 | { "18446744073709551615.log", 18446744073709551615ull, kLogFile }, 37 | }; 38 | for (int i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) { 39 | std::string f = cases[i].fname; 40 | ASSERT_TRUE(ParseFileName(f, &number, &type)) << f; 41 | ASSERT_EQ(cases[i].type, type) << f; 42 | ASSERT_EQ(cases[i].number, number) << f; 43 | } 44 | 45 | // Errors 46 | static const char* errors[] = { 47 | "", 48 | "foo", 49 | "foo-dx-100.log", 50 | ".log", 51 | "", 52 | "manifest", 53 | "CURREN", 54 | "CURRENTX", 55 | "MANIFES", 56 | "MANIFEST", 57 | "MANIFEST-", 58 | "XMANIFEST-3", 59 | "MANIFEST-3x", 60 | "LOC", 61 | "LOCKx", 62 | "LO", 63 | "LOGx", 64 | "18446744073709551616.log", 65 | "184467440737095516150.log", 66 | "100", 67 | "100.", 68 | "100.lop" 69 | }; 70 | for (int i = 0; i < sizeof(errors) / sizeof(errors[0]); i++) { 71 | std::string f = errors[i]; 72 | ASSERT_TRUE(!ParseFileName(f, &number, &type)) << f; 73 | }; 74 | } 75 | 76 | TEST(FileNameTest, Construction) { 77 | uint64_t number; 78 | FileType type; 79 | std::string fname; 80 | 81 | fname = CurrentFileName("foo"); 82 | ASSERT_EQ("foo/", std::string(fname.data(), 4)); 83 | ASSERT_TRUE(ParseFileName(fname.c_str() + 4, &number, &type)); 84 | ASSERT_EQ(0, number); 85 | ASSERT_EQ(kCurrentFile, type); 86 | 87 | fname = LockFileName("foo"); 88 | ASSERT_EQ("foo/", std::string(fname.data(), 4)); 89 | ASSERT_TRUE(ParseFileName(fname.c_str() + 4, &number, &type)); 90 | ASSERT_EQ(0, number); 91 | ASSERT_EQ(kDBLockFile, type); 92 | 93 | fname = LogFileName("foo", 192); 94 | ASSERT_EQ("foo/", std::string(fname.data(), 4)); 95 | ASSERT_TRUE(ParseFileName(fname.c_str() + 4, &number, &type)); 96 | ASSERT_EQ(192, number); 97 | ASSERT_EQ(kLogFile, type); 98 | 99 | fname = TableFileName("bar", 200); 100 | ASSERT_EQ("bar/", std::string(fname.data(), 4)); 101 | ASSERT_TRUE(ParseFileName(fname.c_str() + 4, &number, &type)); 102 | ASSERT_EQ(200, number); 103 | ASSERT_EQ(kTableFile, type); 104 | 105 | fname = DescriptorFileName("bar", 100); 106 | ASSERT_EQ("bar/", std::string(fname.data(), 4)); 107 | ASSERT_TRUE(ParseFileName(fname.c_str() + 4, &number, &type)); 108 | ASSERT_EQ(100, number); 109 | ASSERT_EQ(kDescriptorFile, type); 110 | 111 | fname = TempFileName("tmp", 999); 112 | ASSERT_EQ("tmp/", std::string(fname.data(), 4)); 113 | ASSERT_TRUE(ParseFileName(fname.c_str() + 4, &number, &type)); 114 | ASSERT_EQ(999, number); 115 | ASSERT_EQ(kTempFile, type); 116 | } 117 | 118 | } 119 | 120 | int main(int argc, char** argv) { 121 | return leveldb::test::RunAllTests(); 122 | } 123 | -------------------------------------------------------------------------------- /deps/leveldb/include/leveldb/iterator.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | // 5 | // An iterator yields a sequence of key/value pairs from a source. 6 | // The following class defines the interface. Multiple implementations 7 | // are provided by this library. In particular, iterators are provided 8 | // to access the contents of a Table or a DB. 9 | // 10 | // Multiple threads can invoke const methods on an Iterator without 11 | // external synchronization, but if any of the threads may call a 12 | // non-const method, all threads accessing the same Iterator must use 13 | // external synchronization. 14 | 15 | #ifndef STORAGE_LEVELDB_INCLUDE_ITERATOR_H_ 16 | #define STORAGE_LEVELDB_INCLUDE_ITERATOR_H_ 17 | 18 | #include "leveldb/slice.h" 19 | #include "leveldb/status.h" 20 | 21 | namespace leveldb { 22 | 23 | class Iterator { 24 | public: 25 | Iterator(); 26 | virtual ~Iterator(); 27 | 28 | // An iterator is either positioned at a key/value pair, or 29 | // not valid. This method returns true iff the iterator is valid. 30 | virtual bool Valid() const = 0; 31 | 32 | // Position at the first key in the source. The iterator is Valid() 33 | // after this call iff the source is not empty. 34 | virtual void SeekToFirst() = 0; 35 | 36 | // Position at the last key in the source. The iterator is 37 | // Valid() after this call iff the source is not empty. 38 | virtual void SeekToLast() = 0; 39 | 40 | // Position at the first key in the source that at or past target 41 | // The iterator is Valid() after this call iff the source contains 42 | // an entry that comes at or past target. 43 | virtual void Seek(const Slice& target) = 0; 44 | 45 | // Moves to the next entry in the source. After this call, Valid() is 46 | // true iff the iterator was not positioned at the last entry in the source. 47 | // REQUIRES: Valid() 48 | virtual void Next() = 0; 49 | 50 | // Moves to the previous entry in the source. After this call, Valid() is 51 | // true iff the iterator was not positioned at the first entry in source. 52 | // REQUIRES: Valid() 53 | virtual void Prev() = 0; 54 | 55 | // Return the key for the current entry. The underlying storage for 56 | // the returned slice is valid only until the next modification of 57 | // the iterator. 58 | // REQUIRES: Valid() 59 | virtual Slice key() const = 0; 60 | 61 | // Return the value for the current entry. The underlying storage for 62 | // the returned slice is valid only until the next modification of 63 | // the iterator. 64 | // REQUIRES: !AtEnd() && !AtStart() 65 | virtual Slice value() const = 0; 66 | 67 | // If an error has occurred, return it. Else return an ok status. 68 | virtual Status status() const = 0; 69 | 70 | // Clients are allowed to register function/arg1/arg2 triples that 71 | // will be invoked when this iterator is destroyed. 72 | // 73 | // Note that unlike all of the preceding methods, this method is 74 | // not abstract and therefore clients should not override it. 75 | typedef void (*CleanupFunction)(void* arg1, void* arg2); 76 | void RegisterCleanup(CleanupFunction function, void* arg1, void* arg2); 77 | 78 | private: 79 | struct Cleanup { 80 | CleanupFunction function; 81 | void* arg1; 82 | void* arg2; 83 | Cleanup* next; 84 | }; 85 | Cleanup cleanup_; 86 | 87 | // No copying allowed 88 | Iterator(const Iterator&); 89 | void operator=(const Iterator&); 90 | }; 91 | 92 | // Return an empty iterator (yields nothing). 93 | extern Iterator* NewEmptyIterator(); 94 | 95 | // Return an empty iterator with the specified status. 96 | extern Iterator* NewErrorIterator(const Status& status); 97 | 98 | } 99 | 100 | #endif // STORAGE_LEVELDB_INCLUDE_ITERATOR_H_ 101 | -------------------------------------------------------------------------------- /deps/leveldb/include/leveldb/cache.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | // 5 | // A Cache is an interface that maps keys to values. It has internal 6 | // synchronization and may be safely accessed concurrently from 7 | // multiple threads. It may automatically evict entries to make room 8 | // for new entries. Values have a specified charge against the cache 9 | // capacity. For example, a cache where the values are variable 10 | // length strings, may use the length of the string as the charge for 11 | // the string. 12 | // 13 | // A builtin cache implementation with a least-recently-used eviction 14 | // policy is provided. Clients may use their own implementations if 15 | // they want something more sophisticated (like scan-resistance, a 16 | // custom eviction policy, variable cache sizing, etc.) 17 | 18 | #ifndef STORAGE_LEVELDB_INCLUDE_CACHE_H_ 19 | #define STORAGE_LEVELDB_INCLUDE_CACHE_H_ 20 | 21 | #include 22 | #include "leveldb/slice.h" 23 | 24 | namespace leveldb { 25 | 26 | class Cache; 27 | 28 | // Create a new cache with a fixed size capacity. This implementation 29 | // of Cache uses a least-recently-used eviction policy. 30 | extern Cache* NewLRUCache(size_t capacity); 31 | 32 | class Cache { 33 | public: 34 | Cache() { } 35 | 36 | // Destroys all existing entries by calling the "deleter" 37 | // function that was passed to the constructor. 38 | virtual ~Cache(); 39 | 40 | // Opaque handle to an entry stored in the cache. 41 | struct Handle { }; 42 | 43 | // Insert a mapping from key->value into the cache and assign it 44 | // the specified charge against the total cache capacity. 45 | // 46 | // Returns a handle that corresponds to the mapping. The caller 47 | // must call this->Release(handle) when the returned mapping is no 48 | // longer needed. 49 | // 50 | // When the inserted entry is no longer needed, the key and 51 | // value will be passed to "deleter". 52 | virtual Handle* Insert(const Slice& key, void* value, size_t charge, 53 | void (*deleter)(const Slice& key, void* value)) = 0; 54 | 55 | // If the cache has no mapping for "key", returns NULL. 56 | // 57 | // Else return a handle that corresponds to the mapping. The caller 58 | // must call this->Release(handle) when the returned mapping is no 59 | // longer needed. 60 | virtual Handle* Lookup(const Slice& key) = 0; 61 | 62 | // Release a mapping returned by a previous Lookup(). 63 | // REQUIRES: handle must not have been released yet. 64 | // REQUIRES: handle must have been returned by a method on *this. 65 | virtual void Release(Handle* handle) = 0; 66 | 67 | // Return the value encapsulated in a handle returned by a 68 | // successful Lookup(). 69 | // REQUIRES: handle must not have been released yet. 70 | // REQUIRES: handle must have been returned by a method on *this. 71 | virtual void* Value(Handle* handle) = 0; 72 | 73 | // If the cache contains entry for key, erase it. Note that the 74 | // underlying entry will be kept around until all existing handles 75 | // to it have been released. 76 | virtual void Erase(const Slice& key) = 0; 77 | 78 | // Return a new numeric id. May be used by multiple clients who are 79 | // sharing the same cache to partition the key space. Typically the 80 | // client will allocate a new id at startup and prepend the id to 81 | // its cache keys. 82 | virtual uint64_t NewId() = 0; 83 | 84 | private: 85 | void LRU_Remove(Handle* e); 86 | void LRU_Append(Handle* e); 87 | void Unref(Handle* e); 88 | 89 | struct Rep; 90 | Rep* rep_; 91 | 92 | // No copying allowed 93 | Cache(const Cache&); 94 | void operator=(const Cache&); 95 | }; 96 | 97 | } 98 | 99 | #endif // STORAGE_LEVELDB_UTIL_CACHE_H_ 100 | -------------------------------------------------------------------------------- /deps/leveldb/db/log_reader.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #ifndef STORAGE_LEVELDB_DB_LOG_READER_H_ 6 | #define STORAGE_LEVELDB_DB_LOG_READER_H_ 7 | 8 | #include 9 | 10 | #include "db/log_format.h" 11 | #include "leveldb/slice.h" 12 | #include "leveldb/status.h" 13 | 14 | namespace leveldb { 15 | 16 | class SequentialFile; 17 | 18 | namespace log { 19 | 20 | class Reader { 21 | public: 22 | // Interface for reporting errors. 23 | class Reporter { 24 | public: 25 | virtual ~Reporter(); 26 | 27 | // Some corruption was detected. "size" is the approximate number 28 | // of bytes dropped due to the corruption. 29 | virtual void Corruption(size_t bytes, const Status& status) = 0; 30 | }; 31 | 32 | // Create a reader that will return log records from "*file". 33 | // "*file" must remain live while this Reader is in use. 34 | // 35 | // If "reporter" is non-NULL, it is notified whenever some data is 36 | // dropped due to a detected corruption. "*reporter" must remain 37 | // live while this Reader is in use. 38 | // 39 | // If "checksum" is true, verify checksums if available. 40 | // 41 | // The Reader will start reading at the first record located at physical 42 | // position >= initial_offset within the file. 43 | Reader(SequentialFile* file, Reporter* reporter, bool checksum, 44 | uint64_t initial_offset); 45 | 46 | ~Reader(); 47 | 48 | // Read the next record into *record. Returns true if read 49 | // successfully, false if we hit end of the input. May use 50 | // "*scratch" as temporary storage. The contents filled in *record 51 | // will only be valid until the next mutating operation on this 52 | // reader or the next mutation to *scratch. 53 | bool ReadRecord(Slice* record, std::string* scratch); 54 | 55 | // Returns the physical offset of the last record returned by ReadRecord. 56 | // 57 | // Undefined before the first call to ReadRecord. 58 | uint64_t LastRecordOffset(); 59 | 60 | private: 61 | SequentialFile* const file_; 62 | Reporter* const reporter_; 63 | bool const checksum_; 64 | char* const backing_store_; 65 | Slice buffer_; 66 | bool eof_; // Last Read() indicated EOF by returning < kBlockSize 67 | 68 | // Offset of the last record returned by ReadRecord. 69 | uint64_t last_record_offset_; 70 | // Offset of the first location past the end of buffer_. 71 | uint64_t end_of_buffer_offset_; 72 | 73 | // Offset at which to start looking for the first record to return 74 | uint64_t const initial_offset_; 75 | 76 | // Extend record types with the following special values 77 | enum { 78 | kEof = kMaxRecordType + 1, 79 | // Returned whenever we find an invalid physical record. 80 | // Currently there are three situations in which this happens: 81 | // * The record has an invalid CRC (ReadPhysicalRecord reports a drop) 82 | // * The record is a 0-length record (No drop is reported) 83 | // * The record is below constructor's initial_offset (No drop is reported) 84 | kBadRecord = kMaxRecordType + 2 85 | }; 86 | 87 | // Skips all blocks that are completely before "initial_offset_". 88 | // 89 | // Returns true on success. Handles reporting. 90 | bool SkipToInitialBlock(); 91 | 92 | // Return type, or one of the preceding special values 93 | unsigned int ReadPhysicalRecord(Slice* result); 94 | 95 | // Reports dropped bytes to the reporter. 96 | // buffer_ must be updated to remove the dropped bytes prior to invocation. 97 | void ReportCorruption(size_t bytes, const char* reason); 98 | void ReportDrop(size_t bytes, const Status& reason); 99 | 100 | // No copying allowed 101 | Reader(const Reader&); 102 | void operator=(const Reader&); 103 | }; 104 | 105 | } 106 | } 107 | 108 | #endif // STORAGE_LEVELDB_DB_LOG_READER_H_ 109 | -------------------------------------------------------------------------------- /deps/leveldb/base/atomicops_internals_x86_gcc.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // This module gets enough CPU information to optimize the 6 | // atomicops module on x86. 7 | 8 | #include 9 | 10 | #include "base/atomicops.h" 11 | #include "base/basictypes.h" 12 | 13 | // This file only makes sense with atomicops_internals_x86_gcc.h -- it 14 | // depends on structs that are defined in that file. If atomicops.h 15 | // doesn't sub-include that file, then we aren't needed, and shouldn't 16 | // try to do anything. 17 | #ifdef BASE_ATOMICOPS_INTERNALS_X86_GCC_H_ 18 | 19 | // Inline cpuid instruction. In PIC compilations, %ebx contains the address 20 | // of the global offset table. To avoid breaking such executables, this code 21 | // must preserve that register's value across cpuid instructions. 22 | #if defined(__i386__) 23 | #define cpuid(a, b, c, d, inp) \ 24 | asm ("mov %%ebx, %%edi\n" \ 25 | "cpuid\n" \ 26 | "xchg %%edi, %%ebx\n" \ 27 | : "=a" (a), "=D" (b), "=c" (c), "=d" (d) : "a" (inp)) 28 | #elif defined (__x86_64__) 29 | #define cpuid(a, b, c, d, inp) \ 30 | asm ("mov %%rbx, %%rdi\n" \ 31 | "cpuid\n" \ 32 | "xchg %%rdi, %%rbx\n" \ 33 | : "=a" (a), "=D" (b), "=c" (c), "=d" (d) : "a" (inp)) 34 | #endif 35 | 36 | #if defined(cpuid) // initialize the struct only on x86 37 | 38 | // Set the flags so that code will run correctly and conservatively, so even 39 | // if we haven't been initialized yet, we're probably single threaded, and our 40 | // default values should hopefully be pretty safe. 41 | struct AtomicOps_x86CPUFeatureStruct AtomicOps_Internalx86CPUFeatures = { 42 | false, // bug can't exist before process spawns multiple threads 43 | false, // no SSE2 44 | }; 45 | 46 | // Initialize the AtomicOps_Internalx86CPUFeatures struct. 47 | static void AtomicOps_Internalx86CPUFeaturesInit() { 48 | uint32 eax; 49 | uint32 ebx; 50 | uint32 ecx; 51 | uint32 edx; 52 | 53 | // Get vendor string (issue CPUID with eax = 0) 54 | cpuid(eax, ebx, ecx, edx, 0); 55 | char vendor[13]; 56 | memcpy(vendor, &ebx, 4); 57 | memcpy(vendor + 4, &edx, 4); 58 | memcpy(vendor + 8, &ecx, 4); 59 | vendor[12] = 0; 60 | 61 | // get feature flags in ecx/edx, and family/model in eax 62 | cpuid(eax, ebx, ecx, edx, 1); 63 | 64 | int family = (eax >> 8) & 0xf; // family and model fields 65 | int model = (eax >> 4) & 0xf; 66 | if (family == 0xf) { // use extended family and model fields 67 | family += (eax >> 20) & 0xff; 68 | model += ((eax >> 16) & 0xf) << 4; 69 | } 70 | 71 | // Opteron Rev E has a bug in which on very rare occasions a locked 72 | // instruction doesn't act as a read-acquire barrier if followed by a 73 | // non-locked read-modify-write instruction. Rev F has this bug in 74 | // pre-release versions, but not in versions released to customers, 75 | // so we test only for Rev E, which is family 15, model 32..63 inclusive. 76 | if (strcmp(vendor, "AuthenticAMD") == 0 && // AMD 77 | family == 15 && 78 | 32 <= model && model <= 63) { 79 | AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug = true; 80 | } else { 81 | AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug = false; 82 | } 83 | 84 | // edx bit 26 is SSE2 which we use to tell use whether we can use mfence 85 | AtomicOps_Internalx86CPUFeatures.has_sse2 = ((edx >> 26) & 1); 86 | } 87 | 88 | namespace { 89 | 90 | class AtomicOpsx86Initializer { 91 | public: 92 | AtomicOpsx86Initializer() { 93 | AtomicOps_Internalx86CPUFeaturesInit(); 94 | } 95 | }; 96 | 97 | // A global to get use initialized on startup via static initialization :/ 98 | AtomicOpsx86Initializer g_initer; 99 | 100 | } // namespace 101 | 102 | #endif // if x86 103 | 104 | #endif // ifdef BASE_ATOMICOPS_INTERNALS_X86_GCC_H_ 105 | -------------------------------------------------------------------------------- /deps/leveldb/table/block_builder.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | // 5 | // BlockBuilder generates blocks where keys are prefix-compressed: 6 | // 7 | // When we store a key, we drop the prefix shared with the previous 8 | // string. This helps reduce the space requirement significantly. 9 | // Furthermore, once every K keys, we do not apply the prefix 10 | // compression and store the entire key. We call this a "restart 11 | // point". The tail end of the block stores the offsets of all of the 12 | // restart points, and can be used to do a binary search when looking 13 | // for a particular key. Values are stored as-is (without compression) 14 | // immediately following the corresponding key. 15 | // 16 | // An entry for a particular key-value pair has the form: 17 | // shared_bytes: varint32 18 | // unshared_bytes: varint32 19 | // value_length: varint32 20 | // key_delta: char[unshared_bytes] 21 | // value: char[value_length] 22 | // shared_bytes == 0 for restart points. 23 | // 24 | // The trailer of the block has the form: 25 | // restarts: uint32[num_restarts] 26 | // num_restarts: uint32 27 | // restarts[i] contains the offset within the block of the ith restart point. 28 | 29 | #include "table/block_builder.h" 30 | 31 | #include 32 | #include 33 | #include "leveldb/comparator.h" 34 | #include "leveldb/table_builder.h" 35 | #include "util/coding.h" 36 | 37 | namespace leveldb { 38 | 39 | BlockBuilder::BlockBuilder(const Options* options) 40 | : options_(options), 41 | restarts_(), 42 | counter_(0), 43 | finished_(false) { 44 | assert(options->block_restart_interval >= 1); 45 | restarts_.push_back(0); // First restart point is at offset 0 46 | } 47 | 48 | void BlockBuilder::Reset() { 49 | buffer_.clear(); 50 | restarts_.clear(); 51 | restarts_.push_back(0); // First restart point is at offset 0 52 | counter_ = 0; 53 | finished_ = false; 54 | last_key_.clear(); 55 | } 56 | 57 | size_t BlockBuilder::CurrentSizeEstimate() const { 58 | return (buffer_.size() + // Raw data buffer 59 | restarts_.size() * sizeof(uint32_t) + // Restart array 60 | sizeof(uint32_t)); // Restart array length 61 | } 62 | 63 | Slice BlockBuilder::Finish() { 64 | // Append restart array 65 | for (size_t i = 0; i < restarts_.size(); i++) { 66 | PutFixed32(&buffer_, restarts_[i]); 67 | } 68 | PutFixed32(&buffer_, restarts_.size()); 69 | finished_ = true; 70 | return Slice(buffer_); 71 | } 72 | 73 | void BlockBuilder::Add(const Slice& key, const Slice& value) { 74 | Slice last_key_piece(last_key_); 75 | assert(!finished_); 76 | assert(counter_ <= options_->block_restart_interval); 77 | assert(buffer_.empty() // No values yet? 78 | || options_->comparator->Compare(key, last_key_piece) > 0); 79 | size_t shared = 0; 80 | if (counter_ < options_->block_restart_interval) { 81 | // See how much sharing to do with previous string 82 | const size_t min_length = std::min(last_key_piece.size(), key.size()); 83 | while ((shared < min_length) && (last_key_piece[shared] == key[shared])) { 84 | shared++; 85 | } 86 | } else { 87 | // Restart compression 88 | restarts_.push_back(buffer_.size()); 89 | counter_ = 0; 90 | } 91 | const size_t non_shared = key.size() - shared; 92 | 93 | // Add "" to buffer_ 94 | PutVarint32(&buffer_, shared); 95 | PutVarint32(&buffer_, non_shared); 96 | PutVarint32(&buffer_, value.size()); 97 | 98 | // Add string delta to buffer_ followed by value 99 | buffer_.append(key.data() + shared, non_shared); 100 | buffer_.append(value.data(), value.size()); 101 | 102 | // Update state 103 | last_key_.resize(shared); 104 | last_key_.append(key.data() + shared, non_shared); 105 | assert(Slice(last_key_) == key); 106 | counter_++; 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /deps/leveldb/port/port_android.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | // 5 | // See port_example.h for documentation for the following types/functions. 6 | 7 | #ifndef STORAGE_LEVELDB_PORT_PORT_ANDROID_H_ 8 | #define STORAGE_LEVELDB_PORT_PORT_ANDROID_H_ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | // Collapse the plethora of ARM flavors available to an easier to manage set 18 | // Defs reference is at https://wiki.edubuntu.org/ARM/Thumb2PortingHowto 19 | #if defined(__ARM_ARCH_6__) || \ 20 | defined(__ARM_ARCH_6J__) || \ 21 | defined(__ARM_ARCH_6K__) || \ 22 | defined(__ARM_ARCH_6Z__) || \ 23 | defined(__ARM_ARCH_6T2__) || \ 24 | defined(__ARM_ARCH_6ZK__) || \ 25 | defined(__ARM_ARCH_7__) || \ 26 | defined(__ARM_ARCH_7R__) || \ 27 | defined(__ARM_ARCH_7A__) 28 | #define ARMV6_OR_7 1 29 | #endif 30 | 31 | extern "C" { 32 | size_t fread_unlocked(void *a, size_t b, size_t c, FILE *d); 33 | size_t fwrite_unlocked(const void *a, size_t b, size_t c, FILE *d); 34 | int fflush_unlocked(FILE *f); 35 | int fdatasync (int fd); 36 | } 37 | 38 | namespace leveldb { 39 | namespace port { 40 | 41 | static const bool kLittleEndian = __BYTE_ORDER == __LITTLE_ENDIAN; 42 | 43 | class CondVar; 44 | 45 | class Mutex { 46 | public: 47 | Mutex(); 48 | ~Mutex(); 49 | 50 | void Lock(); 51 | void Unlock(); 52 | void AssertHeld() { 53 | //TODO(gabor): How can I implement this? 54 | } 55 | 56 | private: 57 | friend class CondVar; 58 | pthread_mutex_t mu_; 59 | 60 | // No copying 61 | Mutex(const Mutex&); 62 | void operator=(const Mutex&); 63 | }; 64 | 65 | class CondVar { 66 | public: 67 | explicit CondVar(Mutex* mu); 68 | ~CondVar(); 69 | void Wait(); 70 | void Signal(); 71 | void SignalAll(); 72 | private: 73 | Mutex* mu_; 74 | pthread_cond_t cv_; 75 | }; 76 | 77 | #ifndef ARMV6_OR_7 78 | // On ARM chipsets = V6 92 | #ifdef ARMV6_OR_7 93 | __asm__ __volatile__("dmb" : : : "memory"); 94 | #else 95 | pLinuxKernelMemoryBarrier(); 96 | #endif 97 | } 98 | 99 | public: 100 | AtomicPointer() { } 101 | explicit AtomicPointer(void* v) : rep_(v) { } 102 | inline void* Acquire_Load() const { 103 | void* r = rep_; 104 | MemoryBarrier(); 105 | return r; 106 | } 107 | inline void Release_Store(void* v) { 108 | MemoryBarrier(); 109 | rep_ = v; 110 | } 111 | inline void* NoBarrier_Load() const { 112 | void* r = rep_; 113 | return r; 114 | } 115 | inline void NoBarrier_Store(void* v) { 116 | rep_ = v; 117 | } 118 | }; 119 | 120 | // TODO(gabor): Implement compress 121 | inline bool Snappy_Compress( 122 | const char* input, 123 | size_t input_length, 124 | std::string* output) { 125 | return false; 126 | } 127 | 128 | // TODO(gabor): Implement uncompress 129 | inline bool Snappy_Uncompress( 130 | const char* input_data, 131 | size_t input_length, 132 | std::string* output) { 133 | return false; 134 | } 135 | 136 | inline uint64_t ThreadIdentifier() { 137 | pthread_t tid = pthread_self(); 138 | uint64_t r = 0; 139 | memcpy(&r, &tid, sizeof(r) < sizeof(tid) ? sizeof(r) : sizeof(tid)); 140 | return r; 141 | } 142 | 143 | inline bool GetHeapProfile(void (*func)(void*, const char*, int), void* arg) { 144 | return false; 145 | } 146 | 147 | } 148 | } 149 | 150 | #endif // STORAGE_LEVELDB_PORT_PORT_ANDROID_H_ 151 | -------------------------------------------------------------------------------- /deps/leveldb/base/atomicops_internals_atomicword_compat.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // This file is an internal atomic implementation, use base/atomicops.h instead. 6 | 7 | #ifndef BASE_ATOMICOPS_INTERNALS_ATOMICWORD_COMPAT_H_ 8 | #define BASE_ATOMICOPS_INTERNALS_ATOMICWORD_COMPAT_H_ 9 | #pragma once 10 | 11 | // AtomicWord is a synonym for intptr_t, and Atomic32 is a synonym for int32, 12 | // which in turn means int. On some LP32 platforms, intptr_t is an int, but 13 | // on others, it's a long. When AtomicWord and Atomic32 are based on different 14 | // fundamental types, their pointers are incompatible. 15 | // 16 | // This file defines function overloads to allow both AtomicWord and Atomic32 17 | // data to be used with this interface. 18 | // 19 | // On LP64 platforms, AtomicWord and Atomic64 are both always long, 20 | // so this problem doesn't occur. 21 | 22 | #if !defined(ARCH_CPU_64_BITS) 23 | 24 | namespace base { 25 | namespace subtle { 26 | 27 | inline AtomicWord NoBarrier_CompareAndSwap(volatile AtomicWord* ptr, 28 | AtomicWord old_value, 29 | AtomicWord new_value) { 30 | return NoBarrier_CompareAndSwap( 31 | reinterpret_cast(ptr), old_value, new_value); 32 | } 33 | 34 | inline AtomicWord NoBarrier_AtomicExchange(volatile AtomicWord* ptr, 35 | AtomicWord new_value) { 36 | return NoBarrier_AtomicExchange( 37 | reinterpret_cast(ptr), new_value); 38 | } 39 | 40 | inline AtomicWord NoBarrier_AtomicIncrement(volatile AtomicWord* ptr, 41 | AtomicWord increment) { 42 | return NoBarrier_AtomicIncrement( 43 | reinterpret_cast(ptr), increment); 44 | } 45 | 46 | inline AtomicWord Barrier_AtomicIncrement(volatile AtomicWord* ptr, 47 | AtomicWord increment) { 48 | return Barrier_AtomicIncrement( 49 | reinterpret_cast(ptr), increment); 50 | } 51 | 52 | inline AtomicWord Acquire_CompareAndSwap(volatile AtomicWord* ptr, 53 | AtomicWord old_value, 54 | AtomicWord new_value) { 55 | return base::subtle::Acquire_CompareAndSwap( 56 | reinterpret_cast(ptr), old_value, new_value); 57 | } 58 | 59 | inline AtomicWord Release_CompareAndSwap(volatile AtomicWord* ptr, 60 | AtomicWord old_value, 61 | AtomicWord new_value) { 62 | return base::subtle::Release_CompareAndSwap( 63 | reinterpret_cast(ptr), old_value, new_value); 64 | } 65 | 66 | inline void NoBarrier_Store(volatile AtomicWord *ptr, AtomicWord value) { 67 | NoBarrier_Store( 68 | reinterpret_cast(ptr), value); 69 | } 70 | 71 | inline void Acquire_Store(volatile AtomicWord* ptr, AtomicWord value) { 72 | return base::subtle::Acquire_Store( 73 | reinterpret_cast(ptr), value); 74 | } 75 | 76 | inline void Release_Store(volatile AtomicWord* ptr, AtomicWord value) { 77 | return base::subtle::Release_Store( 78 | reinterpret_cast(ptr), value); 79 | } 80 | 81 | inline AtomicWord NoBarrier_Load(volatile const AtomicWord *ptr) { 82 | return NoBarrier_Load( 83 | reinterpret_cast(ptr)); 84 | } 85 | 86 | inline AtomicWord Acquire_Load(volatile const AtomicWord* ptr) { 87 | return base::subtle::Acquire_Load( 88 | reinterpret_cast(ptr)); 89 | } 90 | 91 | inline AtomicWord Release_Load(volatile const AtomicWord* ptr) { 92 | return base::subtle::Release_Load( 93 | reinterpret_cast(ptr)); 94 | } 95 | 96 | } // namespace base::subtle 97 | } // namespace base 98 | 99 | #endif // !defined(ARCH_CPU_64_BITS) 100 | 101 | #endif // BASE_ATOMICOPS_INTERNALS_ATOMICWORD_COMPAT_H_ 102 | -------------------------------------------------------------------------------- /deps/leveldb/db/memtable.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include "db/memtable.h" 6 | #include "db/dbformat.h" 7 | #include "leveldb/comparator.h" 8 | #include "leveldb/env.h" 9 | #include "leveldb/iterator.h" 10 | #include "util/coding.h" 11 | 12 | namespace leveldb { 13 | 14 | static Slice GetLengthPrefixedSlice(const char* data) { 15 | uint32_t len; 16 | const char* p = data; 17 | p = GetVarint32Ptr(p, p + 5, &len); // +5: we assume "p" is not corrupted 18 | return Slice(p, len); 19 | } 20 | 21 | MemTable::MemTable(const InternalKeyComparator& cmp) 22 | : comparator_(cmp), 23 | refs_(0), 24 | table_(comparator_, &arena_) { 25 | } 26 | 27 | MemTable::~MemTable() { 28 | assert(refs_ == 0); 29 | } 30 | 31 | size_t MemTable::ApproximateMemoryUsage() { return arena_.MemoryUsage(); } 32 | 33 | int MemTable::KeyComparator::operator()(const char* aptr, const char* bptr) 34 | const { 35 | // Internal keys are encoded as length-prefixed strings. 36 | Slice a = GetLengthPrefixedSlice(aptr); 37 | Slice b = GetLengthPrefixedSlice(bptr); 38 | return comparator.Compare(a, b); 39 | } 40 | 41 | // Encode a suitable internal key target for "target" and return it. 42 | // Uses *scratch as scratch space, and the returned pointer will point 43 | // into this scratch space. 44 | static const char* EncodeKey(std::string* scratch, const Slice& target) { 45 | scratch->clear(); 46 | PutVarint32(scratch, target.size()); 47 | scratch->append(target.data(), target.size()); 48 | return scratch->data(); 49 | } 50 | 51 | class MemTableIterator: public Iterator { 52 | public: 53 | explicit MemTableIterator(MemTable* mem, MemTable::Table* table) { 54 | mem_ = mem; 55 | iter_ = new MemTable::Table::Iterator(table); 56 | mem->Ref(); 57 | } 58 | virtual ~MemTableIterator() { 59 | delete iter_; 60 | mem_->Unref(); 61 | } 62 | 63 | virtual bool Valid() const { return iter_->Valid(); } 64 | virtual void Seek(const Slice& k) { iter_->Seek(EncodeKey(&tmp_, k)); } 65 | virtual void SeekToFirst() { iter_->SeekToFirst(); } 66 | virtual void SeekToLast() { iter_->SeekToLast(); } 67 | virtual void Next() { iter_->Next(); } 68 | virtual void Prev() { iter_->Prev(); } 69 | virtual Slice key() const { return GetLengthPrefixedSlice(iter_->key()); } 70 | virtual Slice value() const { 71 | Slice key_slice = GetLengthPrefixedSlice(iter_->key()); 72 | return GetLengthPrefixedSlice(key_slice.data() + key_slice.size()); 73 | } 74 | 75 | virtual Status status() const { return Status::OK(); } 76 | 77 | private: 78 | MemTable* mem_; 79 | MemTable::Table::Iterator* iter_; 80 | std::string tmp_; // For passing to EncodeKey 81 | 82 | // No copying allowed 83 | MemTableIterator(const MemTableIterator&); 84 | void operator=(const MemTableIterator&); 85 | }; 86 | 87 | Iterator* MemTable::NewIterator() { 88 | return new MemTableIterator(this, &table_); 89 | } 90 | 91 | void MemTable::Add(SequenceNumber s, ValueType type, 92 | const Slice& key, 93 | const Slice& value) { 94 | // Format of an entry is concatenation of: 95 | // key_size : varint32 of internal_key.size() 96 | // key bytes : char[internal_key.size()] 97 | // value_size : varint32 of value.size() 98 | // value bytes : char[value.size()] 99 | size_t key_size = key.size(); 100 | size_t val_size = value.size(); 101 | size_t internal_key_size = key_size + 8; 102 | const size_t encoded_len = 103 | VarintLength(internal_key_size) + internal_key_size + 104 | VarintLength(val_size) + val_size; 105 | char* buf = arena_.Allocate(encoded_len); 106 | char* p = EncodeVarint32(buf, internal_key_size); 107 | memcpy(p, key.data(), key_size); 108 | p += key_size; 109 | EncodeFixed64(p, (s << 8) | type); 110 | p += 8; 111 | p = EncodeVarint32(p, val_size); 112 | memcpy(p, value.data(), val_size); 113 | assert((p + val_size) - buf == encoded_len); 114 | table_.Insert(buf); 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /deps/leveldb/db/write_batch.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | // 5 | // WriteBatch::rep_ := 6 | // sequence: fixed64 7 | // count: fixed32 8 | // data: record[count] 9 | // record := 10 | // kTypeValue varstring varstring | 11 | // kTypeDeletion varstring 12 | // varstring := 13 | // len: varint32 14 | // data: uint8[len] 15 | 16 | #include "leveldb/write_batch.h" 17 | 18 | #include "leveldb/db.h" 19 | #include "db/dbformat.h" 20 | #include "db/memtable.h" 21 | #include "db/write_batch_internal.h" 22 | #include "util/coding.h" 23 | 24 | namespace leveldb { 25 | 26 | WriteBatch::WriteBatch() { 27 | Clear(); 28 | } 29 | 30 | WriteBatch::~WriteBatch() { } 31 | 32 | WriteBatch::Handler::~Handler() { } 33 | 34 | void WriteBatch::Clear() { 35 | rep_.clear(); 36 | rep_.resize(12); 37 | } 38 | 39 | Status WriteBatch::Iterate(Handler* handler) const { 40 | Slice input(rep_); 41 | if (input.size() < 12) { 42 | return Status::Corruption("malformed WriteBatch (too small)"); 43 | } 44 | 45 | input.remove_prefix(12); 46 | Slice key, value; 47 | int found = 0; 48 | while (!input.empty()) { 49 | found++; 50 | char tag = input[0]; 51 | input.remove_prefix(1); 52 | switch (tag) { 53 | case kTypeValue: 54 | if (GetLengthPrefixedSlice(&input, &key) && 55 | GetLengthPrefixedSlice(&input, &value)) { 56 | handler->Put(key, value); 57 | } else { 58 | return Status::Corruption("bad WriteBatch Put"); 59 | } 60 | break; 61 | case kTypeDeletion: 62 | if (GetLengthPrefixedSlice(&input, &key)) { 63 | handler->Delete(key); 64 | } else { 65 | return Status::Corruption("bad WriteBatch Delete"); 66 | } 67 | break; 68 | default: 69 | return Status::Corruption("unknown WriteBatch tag"); 70 | } 71 | } 72 | if (found != WriteBatchInternal::Count(this)) { 73 | return Status::Corruption("WriteBatch has wrong count"); 74 | } else { 75 | return Status::OK(); 76 | } 77 | } 78 | 79 | int WriteBatchInternal::Count(const WriteBatch* b) { 80 | return DecodeFixed32(b->rep_.data() + 8); 81 | } 82 | 83 | void WriteBatchInternal::SetCount(WriteBatch* b, int n) { 84 | EncodeFixed32(&b->rep_[8], n); 85 | } 86 | 87 | SequenceNumber WriteBatchInternal::Sequence(const WriteBatch* b) { 88 | return SequenceNumber(DecodeFixed64(b->rep_.data())); 89 | } 90 | 91 | void WriteBatchInternal::SetSequence(WriteBatch* b, SequenceNumber seq) { 92 | EncodeFixed64(&b->rep_[0], seq); 93 | } 94 | 95 | void WriteBatch::Put(const Slice& key, const Slice& value) { 96 | WriteBatchInternal::SetCount(this, WriteBatchInternal::Count(this) + 1); 97 | rep_.push_back(static_cast(kTypeValue)); 98 | PutLengthPrefixedSlice(&rep_, key); 99 | PutLengthPrefixedSlice(&rep_, value); 100 | } 101 | 102 | void WriteBatch::Delete(const Slice& key) { 103 | WriteBatchInternal::SetCount(this, WriteBatchInternal::Count(this) + 1); 104 | rep_.push_back(static_cast(kTypeDeletion)); 105 | PutLengthPrefixedSlice(&rep_, key); 106 | } 107 | 108 | namespace { 109 | class MemTableInserter : public WriteBatch::Handler { 110 | public: 111 | SequenceNumber sequence_; 112 | MemTable* mem_; 113 | 114 | virtual void Put(const Slice& key, const Slice& value) { 115 | mem_->Add(sequence_, kTypeValue, key, value); 116 | sequence_++; 117 | } 118 | virtual void Delete(const Slice& key) { 119 | mem_->Add(sequence_, kTypeDeletion, key, Slice()); 120 | sequence_++; 121 | } 122 | }; 123 | } 124 | 125 | Status WriteBatchInternal::InsertInto(const WriteBatch* b, 126 | MemTable* memtable) { 127 | MemTableInserter inserter; 128 | inserter.sequence_ = WriteBatchInternal::Sequence(b); 129 | inserter.mem_ = memtable; 130 | return b->Iterate(&inserter); 131 | } 132 | 133 | void WriteBatchInternal::SetContents(WriteBatch* b, const Slice& contents) { 134 | assert(contents.size() >= 12); 135 | b->rep_.assign(contents.data(), contents.size()); 136 | } 137 | 138 | } 139 | -------------------------------------------------------------------------------- /deps/leveldb/db/dbformat_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include "db/dbformat.h" 6 | #include "util/logging.h" 7 | #include "util/testharness.h" 8 | 9 | namespace leveldb { 10 | 11 | static std::string IKey(const std::string& user_key, 12 | uint64_t seq, 13 | ValueType vt) { 14 | std::string encoded; 15 | AppendInternalKey(&encoded, ParsedInternalKey(user_key, seq, vt)); 16 | return encoded; 17 | } 18 | 19 | static std::string Shorten(const std::string& s, const std::string& l) { 20 | std::string result = s; 21 | InternalKeyComparator(BytewiseComparator()).FindShortestSeparator(&result, l); 22 | return result; 23 | } 24 | 25 | static std::string ShortSuccessor(const std::string& s) { 26 | std::string result = s; 27 | InternalKeyComparator(BytewiseComparator()).FindShortSuccessor(&result); 28 | return result; 29 | } 30 | 31 | static void TestKey(const std::string& key, 32 | uint64_t seq, 33 | ValueType vt) { 34 | std::string encoded = IKey(key, seq, vt); 35 | 36 | Slice in(encoded); 37 | ParsedInternalKey decoded("", 0, kTypeValue); 38 | 39 | ASSERT_TRUE(ParseInternalKey(in, &decoded)); 40 | ASSERT_EQ(key, decoded.user_key.ToString()); 41 | ASSERT_EQ(seq, decoded.sequence); 42 | ASSERT_EQ(vt, decoded.type); 43 | 44 | ASSERT_TRUE(!ParseInternalKey(Slice("bar"), &decoded)); 45 | } 46 | 47 | class FormatTest { }; 48 | 49 | TEST(FormatTest, InternalKey_EncodeDecode) { 50 | const char* keys[] = { "", "k", "hello", "longggggggggggggggggggggg" }; 51 | const uint64_t seq[] = { 52 | 1, 2, 3, 53 | (1ull << 8) - 1, 1ull << 8, (1ull << 8) + 1, 54 | (1ull << 16) - 1, 1ull << 16, (1ull << 16) + 1, 55 | (1ull << 32) - 1, 1ull << 32, (1ull << 32) + 1 56 | }; 57 | for (int k = 0; k < sizeof(keys) / sizeof(keys[0]); k++) { 58 | for (int s = 0; s < sizeof(seq) / sizeof(seq[0]); s++) { 59 | TestKey(keys[k], seq[s], kTypeValue); 60 | TestKey("hello", 1, kTypeDeletion); 61 | } 62 | } 63 | } 64 | 65 | TEST(FormatTest, InternalKeyShortSeparator) { 66 | // When user keys are same 67 | ASSERT_EQ(IKey("foo", 100, kTypeValue), 68 | Shorten(IKey("foo", 100, kTypeValue), 69 | IKey("foo", 99, kTypeValue))); 70 | ASSERT_EQ(IKey("foo", 100, kTypeValue), 71 | Shorten(IKey("foo", 100, kTypeValue), 72 | IKey("foo", 101, kTypeValue))); 73 | ASSERT_EQ(IKey("foo", 100, kTypeValue), 74 | Shorten(IKey("foo", 100, kTypeValue), 75 | IKey("foo", 100, kTypeValue))); 76 | ASSERT_EQ(IKey("foo", 100, kTypeValue), 77 | Shorten(IKey("foo", 100, kTypeValue), 78 | IKey("foo", 100, kTypeDeletion))); 79 | 80 | // When user keys are misordered 81 | ASSERT_EQ(IKey("foo", 100, kTypeValue), 82 | Shorten(IKey("foo", 100, kTypeValue), 83 | IKey("bar", 99, kTypeValue))); 84 | 85 | // When user keys are different, but correctly ordered 86 | ASSERT_EQ(IKey("g", kMaxSequenceNumber, kValueTypeForSeek), 87 | Shorten(IKey("foo", 100, kTypeValue), 88 | IKey("hello", 200, kTypeValue))); 89 | 90 | // When start user key is prefix of limit user key 91 | ASSERT_EQ(IKey("foo", 100, kTypeValue), 92 | Shorten(IKey("foo", 100, kTypeValue), 93 | IKey("foobar", 200, kTypeValue))); 94 | 95 | // When limit user key is prefix of start user key 96 | ASSERT_EQ(IKey("foobar", 100, kTypeValue), 97 | Shorten(IKey("foobar", 100, kTypeValue), 98 | IKey("foo", 200, kTypeValue))); 99 | } 100 | 101 | TEST(FormatTest, InternalKeyShortestSuccessor) { 102 | ASSERT_EQ(IKey("g", kMaxSequenceNumber, kValueTypeForSeek), 103 | ShortSuccessor(IKey("foo", 100, kTypeValue))); 104 | ASSERT_EQ(IKey("\xff\xff", 100, kTypeValue), 105 | ShortSuccessor(IKey("\xff\xff", 100, kTypeValue))); 106 | } 107 | 108 | } 109 | 110 | int main(int argc, char** argv) { 111 | return leveldb::test::RunAllTests(); 112 | } 113 | -------------------------------------------------------------------------------- /deps/leveldb/db/filename.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 | 5 | #include 6 | #include 7 | #include "db/filename.h" 8 | #include "db/dbformat.h" 9 | #include "leveldb/env.h" 10 | #include "util/logging.h" 11 | 12 | namespace leveldb { 13 | 14 | static std::string MakeFileName(const std::string& name, uint64_t number, 15 | const char* suffix) { 16 | char buf[100]; 17 | snprintf(buf, sizeof(buf), "/%06llu.%s", 18 | static_cast(number), 19 | suffix); 20 | return name + buf; 21 | } 22 | 23 | std::string LogFileName(const std::string& name, uint64_t number) { 24 | assert(number > 0); 25 | return MakeFileName(name, number, "log"); 26 | } 27 | 28 | std::string TableFileName(const std::string& name, uint64_t number) { 29 | assert(number > 0); 30 | return MakeFileName(name, number, "sst"); 31 | } 32 | 33 | std::string DescriptorFileName(const std::string& dbname, uint64_t number) { 34 | assert(number > 0); 35 | char buf[100]; 36 | snprintf(buf, sizeof(buf), "/MANIFEST-%06llu", 37 | static_cast(number)); 38 | return dbname + buf; 39 | } 40 | 41 | std::string CurrentFileName(const std::string& dbname) { 42 | return dbname + "/CURRENT"; 43 | } 44 | 45 | std::string LockFileName(const std::string& dbname) { 46 | return dbname + "/LOCK"; 47 | } 48 | 49 | std::string TempFileName(const std::string& dbname, uint64_t number) { 50 | assert(number > 0); 51 | return MakeFileName(dbname, number, "dbtmp"); 52 | } 53 | 54 | std::string InfoLogFileName(const std::string& dbname) { 55 | return dbname + "/LOG"; 56 | } 57 | 58 | // Return the name of the old info log file for "dbname". 59 | std::string OldInfoLogFileName(const std::string& dbname) { 60 | return dbname + "/LOG.old"; 61 | } 62 | 63 | 64 | // Owned filenames have the form: 65 | // dbname/CURRENT 66 | // dbname/LOCK 67 | // dbname/LOG 68 | // dbname/LOG.old 69 | // dbname/MANIFEST-[0-9]+ 70 | // dbname/[0-9]+.(log|sst) 71 | bool ParseFileName(const std::string& fname, 72 | uint64_t* number, 73 | FileType* type) { 74 | Slice rest(fname); 75 | if (rest == "CURRENT") { 76 | *number = 0; 77 | *type = kCurrentFile; 78 | } else if (rest == "LOCK") { 79 | *number = 0; 80 | *type = kDBLockFile; 81 | } else if (rest == "LOG" || rest == "LOG.old") { 82 | *number = 0; 83 | *type = kInfoLogFile; 84 | } else if (rest.starts_with("MANIFEST-")) { 85 | rest.remove_prefix(strlen("MANIFEST-")); 86 | uint64_t num; 87 | if (!ConsumeDecimalNumber(&rest, &num)) { 88 | return false; 89 | } 90 | if (!rest.empty()) { 91 | return false; 92 | } 93 | *type = kDescriptorFile; 94 | *number = num; 95 | } else { 96 | // Avoid strtoull() to keep filename format independent of the 97 | // current locale 98 | uint64_t num; 99 | if (!ConsumeDecimalNumber(&rest, &num)) { 100 | return false; 101 | } 102 | Slice suffix = rest; 103 | if (suffix == Slice(".log")) { 104 | *type = kLogFile; 105 | } else if (suffix == Slice(".sst")) { 106 | *type = kTableFile; 107 | } else if (suffix == Slice(".dbtmp")) { 108 | *type = kTempFile; 109 | } else { 110 | return false; 111 | } 112 | *number = num; 113 | } 114 | return true; 115 | } 116 | 117 | Status SetCurrentFile(Env* env, const std::string& dbname, 118 | uint64_t descriptor_number) { 119 | // Remove leading "dbname/" and add newline to manifest file name 120 | std::string manifest = DescriptorFileName(dbname, descriptor_number); 121 | Slice contents = manifest; 122 | assert(contents.starts_with(dbname + "/")); 123 | contents.remove_prefix(dbname.size() + 1); 124 | std::string tmp = TempFileName(dbname, descriptor_number); 125 | Status s = WriteStringToFile(env, contents.ToString() + "\n", tmp); 126 | if (s.ok()) { 127 | s = env->RenameFile(tmp, CurrentFileName(dbname)); 128 | } 129 | if (!s.ok()) { 130 | env->DeleteFile(tmp); 131 | } 132 | return s; 133 | } 134 | 135 | } 136 | --------------------------------------------------------------------------------