├── .npmrc ├── binding.js ├── test ├── abstract-leveldown-test.js ├── gc.js ├── leveldown-test.js ├── common.js ├── electron.js ├── port-libuv-fix-test.js ├── stack-blower.js ├── make.js ├── leak-tester-iterator.js ├── env-cleanup-hook-test.js ├── chained-batch-gc-test.js ├── clear-gc-test.js ├── leak-tester.js ├── empty-range-option-test.js ├── env-cleanup-hook.js ├── compact-range-test.js ├── getproperty-test.js ├── repair-test.js ├── leak-tester-batch.js ├── iterator-gc-test.js ├── iterator-recursion-test.js ├── compression-test.js ├── segfault-test.js └── iterator-test.js ├── .gitmodules ├── deps ├── leveldb │ ├── leveldb-1.20 │ │ ├── .gitignore │ │ ├── AUTHORS │ │ ├── util │ │ │ ├── filter_policy.cc │ │ │ ├── hash.h │ │ │ ├── options.cc │ │ │ ├── env_posix_test_helper.h │ │ │ ├── histogram.h │ │ │ ├── mutexlock.h │ │ │ ├── hash.cc │ │ │ ├── logging.h │ │ │ ├── crc32c.h │ │ │ ├── testutil.cc │ │ │ ├── hash_test.cc │ │ │ ├── arena_test.cc │ │ │ ├── testharness.cc │ │ │ ├── logging.cc │ │ │ ├── crc32c_test.cc │ │ │ ├── arena.h │ │ │ ├── status.cc │ │ │ ├── arena.cc │ │ │ ├── testutil.h │ │ │ ├── env_posix_test.cc │ │ │ ├── random.h │ │ │ ├── comparator.cc │ │ │ ├── env.cc │ │ │ ├── env_test.cc │ │ │ ├── posix_logger.h │ │ │ └── bloom.cc │ │ ├── port │ │ │ ├── README │ │ │ ├── port.h │ │ │ ├── win │ │ │ │ └── stdint.h │ │ │ ├── thread_annotations.h │ │ │ └── port_posix.cc │ │ ├── NEWS │ │ ├── TODO │ │ ├── helpers │ │ │ └── memenv │ │ │ │ └── memenv.h │ │ ├── db │ │ │ ├── db_iter.h │ │ │ ├── log_format.h │ │ │ ├── builder.h │ │ │ ├── version_edit_test.cc │ │ │ ├── log_writer.h │ │ │ ├── write_batch_internal.h │ │ │ ├── leveldbutil.cc │ │ │ ├── snapshot.h │ │ │ ├── table_cache.h │ │ │ ├── builder.cc │ │ │ ├── memtable.h │ │ │ ├── filename.h │ │ │ ├── version_edit.h │ │ │ └── log_writer.cc │ │ ├── table │ │ │ ├── merger.h │ │ │ ├── block.h │ │ │ ├── two_level_iterator.h │ │ │ ├── iterator.cc │ │ │ ├── block_builder.h │ │ │ ├── iterator_wrapper.h │ │ │ ├── filter_block.h │ │ │ └── format.h │ │ ├── include │ │ │ └── leveldb │ │ │ │ ├── dumpfile.h │ │ │ │ ├── write_batch.h │ │ │ │ ├── comparator.h │ │ │ │ ├── filter_policy.h │ │ │ │ ├── table.h │ │ │ │ └── slice.h │ │ ├── LICENSE │ │ ├── CONTRIBUTING.md │ │ ├── issues │ │ │ ├── issue200_test.cc │ │ │ └── issue178_test.cc │ │ └── doc │ │ │ └── log_format.md │ └── port-libuv │ │ ├── win_logger.h │ │ ├── port_uv.cc │ │ ├── atomic_pointer_win.h │ │ ├── uv_condvar.h │ │ └── win_logger.cc └── snappy │ ├── win32 │ ├── config.h │ └── snappy-stubs-public.h │ ├── snappy.gyp │ ├── mac │ └── snappy-stubs-public.h │ ├── freebsd │ └── snappy-stubs-public.h │ ├── linux │ └── snappy-stubs-public.h │ ├── openbsd │ └── snappy-stubs-public.h │ └── solaris │ └── snappy-stubs-public.h ├── .gitignore ├── .github ├── dependabot.yml └── workflows │ ├── test.yml │ └── release.yml ├── .cirrus.yml ├── chained-batch.js ├── .npmignore ├── LICENSE ├── iterator.js ├── binding.gyp └── package.json /.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false -------------------------------------------------------------------------------- /binding.js: -------------------------------------------------------------------------------- 1 | module.exports = require('node-gyp-build')(__dirname) 2 | -------------------------------------------------------------------------------- /test/abstract-leveldown-test.js: -------------------------------------------------------------------------------- 1 | require('abstract-leveldown/test')(require('./common')) 2 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "deps/snappy/snappy"] 2 | path = deps/snappy/snappy 3 | url = https://github.com/google/snappy.git 4 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/.gitignore: -------------------------------------------------------------------------------- 1 | build_config.mk 2 | *.a 3 | *.o 4 | *.dylib* 5 | *.so 6 | *.so.* 7 | *_test 8 | db_bench 9 | leveldbutil 10 | -------------------------------------------------------------------------------- /test/gc.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | // A special entry point to run certain tests with forced gc. 4 | 5 | if (!global.gc) { 6 | console.error('Run with node --expose-gc') 7 | process.exit(1) 8 | } 9 | 10 | require('./cleanup-hanging-iterators-test') 11 | require('./iterator-gc-test') 12 | require('./chained-batch-gc-test') 13 | require('./clear-gc-test') 14 | -------------------------------------------------------------------------------- /test/leveldown-test.js: -------------------------------------------------------------------------------- 1 | const test = require('tape') 2 | const leveldown = require('..') 3 | 4 | test('test database creation non-string location throws', function (t) { 5 | t.throws( 6 | leveldown.bind(null, {}), 7 | /constructor requires a location string argument/, 8 | 'non-string location leveldown() throws' 9 | ) 10 | t.end() 11 | }) 12 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 | 10 | # Partial list of contributors: 11 | Kevin Regan 12 | Johan Bilien 13 | -------------------------------------------------------------------------------- /test/common.js: -------------------------------------------------------------------------------- 1 | const test = require('tape') 2 | const tempy = require('tempy') 3 | const leveldown = require('..') 4 | const suite = require('abstract-leveldown/test') 5 | 6 | module.exports = suite.common({ 7 | test: test, 8 | factory: function () { 9 | return leveldown(tempy.directory()) 10 | }, 11 | 12 | // Opt-in to new tests 13 | clear: true, 14 | getMany: true 15 | }) 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # When adding entries here, remember to also update `.npmignore`. 2 | 3 | node_modules/ 4 | build/ 5 | build-pre-gyp/ 6 | Release/ 7 | deps/*/Debug/ 8 | libleveldb.so 9 | libleveldb.a 10 | leakydb 11 | *.sln 12 | *.vcxproj 13 | *.vcxproj.filters 14 | *.tlog 15 | *.obj 16 | *.1sdk.pdb 17 | *.lastbuildstate 18 | npm-debug.log 19 | prebuilds/ 20 | yarn.lock 21 | .nyc_output 22 | .benchmarks/ 23 | *.csv 24 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: npm 4 | directory: / 5 | schedule: 6 | interval: monthly 7 | ignore: 8 | - dependency-name: dependency-check 9 | - dependency-name: node-gyp 10 | # ESM-only 11 | - dependency-name: tempy 12 | - package-ecosystem: github-actions 13 | directory: / 14 | schedule: 15 | interval: monthly 16 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/util/filter_policy.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 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/filter_policy.h" 6 | 7 | namespace leveldb { 8 | 9 | FilterPolicy::~FilterPolicy() { } 10 | 11 | } // namespace leveldb 12 | -------------------------------------------------------------------------------- /.cirrus.yml: -------------------------------------------------------------------------------- 1 | freebsd_instance: 2 | image_family: freebsd-12-2 3 | 4 | task: 5 | name: FreeBSD 6 | provision_script: 7 | - pkg install -y git node npm 8 | install_script: 9 | - git submodule update --init --recursive 10 | # TODO: fails with "env: npm: No such file or directory" 11 | # - env ELECTRON_SKIP_BINARY_DOWNLOAD=1 npm i --unsafe-perm 12 | # test_script: npm t 13 | test_script: echo skipped 14 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 | -------------------------------------------------------------------------------- /test/electron.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const tape = require('tape') 4 | const electron = require('electron') 5 | const path = require('path') 6 | const glob = require('glob') 7 | const app = electron.app 8 | 9 | process.on('uncaughtException', function (err) { 10 | console.error(err) 11 | app.exit(1) 12 | }) 13 | 14 | app.on('ready', function () { 15 | tape.onFinish(() => app.quit()) 16 | tape.onFailure(() => app.exit(1)) 17 | 18 | for (const file of glob.sync('test/*-test.js')) { 19 | require(path.resolve('.', file)) 20 | } 21 | }) 22 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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/leveldb-1.20/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 | - There have been requests for MultiGet. 11 | 12 | After a range is completely deleted, what gets rid of the 13 | corresponding files if we do no future changes to that range. Make 14 | the conditions for triggering compactions fire in more situations? 15 | -------------------------------------------------------------------------------- /test/port-libuv-fix-test.js: -------------------------------------------------------------------------------- 1 | const test = require('tape') 2 | const path = require('path') 3 | const fs = require('fs') 4 | 5 | test('test port-libuv is being used', function (t) { 6 | const version = fs.readFileSync(path.join(__dirname, '../deps/leveldb/leveldb.gyp'), 'utf8') 7 | .match(/"ldbversion": "([^"]+)"/)[1] 8 | 9 | t.ok(version, 'matched current leveldb version') 10 | 11 | const porth = fs.readFileSync(path.join(__dirname, '../deps/leveldb/leveldb-' + version + '/port/port.h'), 'utf8') 12 | 13 | t.ok(/"port_uv\.h"/.test(porth), 'port.h includes reference to port_uv.h') 14 | 15 | t.end() 16 | }) 17 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/util/hash.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 | // Simple hash function used for internal data structures 6 | 7 | #ifndef STORAGE_LEVELDB_UTIL_HASH_H_ 8 | #define STORAGE_LEVELDB_UTIL_HASH_H_ 9 | 10 | #include 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/leveldb-1.20/helpers/memenv/memenv.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_HELPERS_MEMENV_MEMENV_H_ 6 | #define STORAGE_LEVELDB_HELPERS_MEMENV_MEMENV_H_ 7 | 8 | namespace leveldb { 9 | 10 | class Env; 11 | 12 | // Returns a new environment that stores its data in memory and delegates 13 | // all non-file-storage tasks to base_env. The caller must delete the result 14 | // when it is no longer needed. 15 | // *base_env must remain live while the result is in use. 16 | Env* NewMemEnv(Env* base_env); 17 | 18 | } // namespace leveldb 19 | 20 | #endif // STORAGE_LEVELDB_HELPERS_MEMENV_MEMENV_H_ 21 | -------------------------------------------------------------------------------- /test/stack-blower.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This test uses infinite recursion to test iterator creation with limited 3 | * stack space. In order to isolate the test harness, we run in a different 4 | * process. This is achieved through a fork() command in 5 | * iterator-recursion-test.js. To prevent tap from trying to run this test 6 | * directly, we check for a command-line argument. 7 | */ 8 | const testCommon = require('./common') 9 | 10 | if (process.argv[2] === 'run') { 11 | const db = testCommon.factory() 12 | let depth = 0 13 | 14 | db.open(function () { 15 | function recurse () { 16 | db.iterator({ gte: '0' }) 17 | depth++ 18 | recurse() 19 | } 20 | 21 | try { 22 | recurse() 23 | } catch (e) { 24 | process.send('Catchable error at depth ' + depth) 25 | } 26 | }) 27 | } 28 | -------------------------------------------------------------------------------- /deps/leveldb/port-libuv/win_logger.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 | // Logger implementation for Windows 6 | 7 | #ifndef STORAGE_LEVELDB_UTIL_WIN_LOGGER_H_ 8 | #define STORAGE_LEVELDB_UTIL_WIN_LOGGER_H_ 9 | 10 | #include 11 | #include "leveldb/env.h" 12 | 13 | namespace leveldb { 14 | 15 | class WinLogger : public Logger { 16 | private: 17 | FILE* file_; 18 | public: 19 | explicit WinLogger(FILE* f) : file_(f) { assert(file_); } 20 | virtual ~WinLogger() { 21 | fclose(file_); 22 | } 23 | virtual void Logv(const char* format, va_list ap); 24 | 25 | }; 26 | 27 | } 28 | #endif // STORAGE_LEVELDB_UTIL_WIN_LOGGER_H_ 29 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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_UV) 14 | # include "port_uv.h" 15 | #elif defined(LEVELDB_PLATFORM_POSIX) 16 | # include "port/port_posix.h" 17 | #elif defined(LEVELDB_PLATFORM_CHROMIUM) 18 | # include "port/port_chromium.h" 19 | #endif 20 | 21 | #endif // STORAGE_LEVELDB_PORT_PORT_H_ 22 | -------------------------------------------------------------------------------- /chained-batch.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const util = require('util') 4 | const AbstractChainedBatch = require('abstract-leveldown').AbstractChainedBatch 5 | const binding = require('./binding') 6 | 7 | function ChainedBatch (db) { 8 | AbstractChainedBatch.call(this, db) 9 | this.context = binding.batch_init(db.context) 10 | } 11 | 12 | ChainedBatch.prototype._put = function (key, value) { 13 | binding.batch_put(this.context, key, value) 14 | } 15 | 16 | ChainedBatch.prototype._del = function (key) { 17 | binding.batch_del(this.context, key) 18 | } 19 | 20 | ChainedBatch.prototype._clear = function () { 21 | binding.batch_clear(this.context) 22 | } 23 | 24 | ChainedBatch.prototype._write = function (options, callback) { 25 | binding.batch_write(this.context, options, callback) 26 | } 27 | 28 | util.inherits(ChainedBatch, AbstractChainedBatch) 29 | 30 | module.exports = ChainedBatch 31 | -------------------------------------------------------------------------------- /deps/snappy/win32/config.h: -------------------------------------------------------------------------------- 1 | #include 2 | typedef SSIZE_T ssize_t; 3 | 4 | /* Define to 1 if you have the header file. */ 5 | #define HAVE_WINDOWS_H 1 6 | 7 | /* Name of package */ 8 | #define PACKAGE "snappy" 9 | 10 | /* Define to the address where bug reports for this package should be sent. */ 11 | #define PACKAGE_BUGREPORT "" 12 | 13 | /* Define to the full name of this package. */ 14 | #define PACKAGE_NAME "snappy" 15 | 16 | /* Define to the full name and version of this package. */ 17 | #define PACKAGE_STRING "snappy 1.1.4" 18 | 19 | /* Define to the one symbol short name of this package. */ 20 | #define PACKAGE_TARNAME "snappy" 21 | 22 | /* Define to the version of this package. */ 23 | #define PACKAGE_VERSION "1.1.4" 24 | 25 | /* Define to 1 if you have the ANSI C header files. */ 26 | #define STDC_HEADERS 1 27 | 28 | /* Version number of package */ 29 | #define VERSION "1.1.4" 30 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 | class DBImpl; 15 | 16 | // Return a new iterator that converts internal keys (yielded by 17 | // "*internal_iter") that were live at the specified "sequence" number 18 | // into appropriate user keys. 19 | extern Iterator* NewDBIterator( 20 | DBImpl* db, 21 | const Comparator* user_key_comparator, 22 | Iterator* internal_iter, 23 | SequenceNumber sequence, 24 | uint32_t seed); 25 | 26 | } // namespace leveldb 27 | 28 | #endif // STORAGE_LEVELDB_DB_DB_ITER_H_ 29 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 | max_file_size(2<<20), 25 | compression(kSnappyCompression), 26 | reuse_logs(false), 27 | filter_policy(NULL) { 28 | } 29 | 30 | } // namespace leveldb 31 | -------------------------------------------------------------------------------- /test/make.js: -------------------------------------------------------------------------------- 1 | const test = require('tape') 2 | const testCommon = require('./common') 3 | 4 | function makeTest (name, testFn) { 5 | test(name, function (t) { 6 | const db = testCommon.factory() 7 | const done = function (err, close) { 8 | t.ifError(err, 'no error from done()') 9 | 10 | if (close === false) { 11 | t.end() 12 | return 13 | } 14 | 15 | db.close(function (err) { 16 | t.ifError(err, 'no error from close()') 17 | t.end() 18 | }) 19 | } 20 | db.open(function (err) { 21 | t.ifError(err, 'no error from open()') 22 | db.batch([ 23 | { type: 'put', key: 'one', value: '1' }, 24 | { type: 'put', key: 'two', value: '2' }, 25 | { type: 'put', key: 'three', value: '3' } 26 | ], function (err) { 27 | t.ifError(err, 'no error from batch()') 28 | testFn(db, t, done) 29 | }) 30 | }) 31 | }) 32 | } 33 | 34 | module.exports = makeTest 35 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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/leveldb-1.20/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 | } // namespace leveldb 25 | 26 | #endif // STORAGE_LEVELDB_TABLE_MERGER_H_ 27 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/include/leveldb/dumpfile.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 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_DUMPFILE_H_ 6 | #define STORAGE_LEVELDB_INCLUDE_DUMPFILE_H_ 7 | 8 | #include 9 | #include "leveldb/env.h" 10 | #include "leveldb/status.h" 11 | 12 | namespace leveldb { 13 | 14 | // Dump the contents of the file named by fname in text format to 15 | // *dst. Makes a sequence of dst->Append() calls; each call is passed 16 | // the newline-terminated text corresponding to a single item found 17 | // in the file. 18 | // 19 | // Returns a non-OK result if fname does not name a leveldb storage 20 | // file, or if the file cannot be read. 21 | Status DumpFile(Env* env, const std::string& fname, WritableFile* dst); 22 | 23 | } // namespace leveldb 24 | 25 | #endif // STORAGE_LEVELDB_INCLUDE_DUMPFILE_H_ 26 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | deps/leveldb/leveldb-basho/ 2 | deps/leveldb/leveldb-hyper/ 3 | deps/leveldb/leveldb-rocksdb/ 4 | deps/leveldb/leveldb-*/doc/ 5 | deps/leveldb/leveldb-*/README.md 6 | deps/leveldb/leveldb-*/CONTRIBUTING.md 7 | deps/leveldb/leveldb-*/port/README 8 | deps/snappy/snappy/testdata/ 9 | deps/snappy/snappy/.appveyor.yml 10 | deps/snappy/snappy/.git 11 | deps/snappy/snappy/.travis.yml 12 | deps/snappy/snappy/CONTRIBUTING.md 13 | deps/snappy/snappy/README.md 14 | deps/snappy/snappy/*.txt 15 | README 16 | INSTALL 17 | NEWS 18 | AUTHORS 19 | TODO 20 | 21 | # Build artifacts 22 | deps/*/Release/ 23 | deps/*/Debug/ 24 | *.tar.gz 25 | build/ 26 | build-pre-gyp/ 27 | libleveldb.so 28 | libleveldb.a 29 | *.sln 30 | *.vcxproj 31 | *.vcxproj.filters 32 | .vscode 33 | 34 | # Benchmarks and tests 35 | test/ 36 | .benchmarks/ 37 | *.csv 38 | 39 | # Misc 40 | .nyc_output/ 41 | yarn.lock 42 | .gitmodules 43 | .github 44 | .travis.yml 45 | .cirrus.yml 46 | appveyor.yml 47 | 48 | # Unknown 49 | leakydb 50 | test-data.tar 51 | test-data.db.tar 52 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/util/env_posix_test_helper.h: -------------------------------------------------------------------------------- 1 | // Copyright 2017 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_ENV_POSIX_TEST_HELPER_H_ 6 | #define STORAGE_LEVELDB_UTIL_ENV_POSIX_TEST_HELPER_H_ 7 | 8 | namespace leveldb { 9 | 10 | class EnvPosixTest; 11 | 12 | // A helper for the POSIX Env to facilitate testing. 13 | class EnvPosixTestHelper { 14 | private: 15 | friend class EnvPosixTest; 16 | 17 | // Set the maximum number of read-only files that will be opened. 18 | // Must be called before creating an Env. 19 | static void SetReadOnlyFDLimit(int limit); 20 | 21 | // Set the maximum number of read-only files that will be mapped via mmap. 22 | // Must be called before creating an Env. 23 | static void SetReadOnlyMMapLimit(int limit); 24 | }; 25 | 26 | } // namespace leveldb 27 | 28 | #endif // STORAGE_LEVELDB_UTIL_ENV_POSIX_TEST_HELPER_H_ 29 | -------------------------------------------------------------------------------- /test/leak-tester-iterator.js: -------------------------------------------------------------------------------- 1 | const db = require('./common').factory() 2 | 3 | let count = 0 4 | let rssBase 5 | 6 | if (!global.gc) { 7 | console.error('To force GC, run with "node --expose-gc"') 8 | } 9 | 10 | function run () { 11 | const it = db.iterator() 12 | 13 | it.next(function (err) { 14 | if (err) throw err 15 | 16 | it.end(function (err) { 17 | if (err) throw err 18 | 19 | if (!rssBase) { 20 | rssBase = process.memoryUsage().rss 21 | } 22 | 23 | if (++count % 1000 === 0) { 24 | if (global.gc) global.gc() 25 | 26 | const rss = process.memoryUsage().rss 27 | const percent = Math.round((rss / rssBase) * 100) 28 | const mb = Math.round(rss / 1024 / 1024) 29 | 30 | console.log('count = %d, rss = %d% %dM', count, percent, mb) 31 | } 32 | 33 | run() 34 | }) 35 | }) 36 | } 37 | 38 | db.open(function (err) { 39 | if (err) throw err 40 | 41 | db.put('key', 'value', function (err) { 42 | if (err) throw err 43 | run() 44 | }) 45 | }) 46 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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.md 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), length (2 bytes), type (1 byte). 30 | static const int kHeaderSize = 4 + 2 + 1; 31 | 32 | } // namespace log 33 | } // namespace leveldb 34 | 35 | #endif // STORAGE_LEVELDB_DB_LOG_FORMAT_H_ 36 | -------------------------------------------------------------------------------- /deps/leveldb/port-libuv/port_uv.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_uv.h" 6 | 7 | #include 8 | #include 9 | #include 10 | #include "util/logging.h" 11 | 12 | namespace leveldb { 13 | namespace port { 14 | 15 | Mutex::Mutex() { uv_mutex_init(&mu_); } 16 | 17 | Mutex::~Mutex() { uv_mutex_destroy(&mu_); } 18 | 19 | void Mutex::Lock() { uv_mutex_lock(&mu_); } 20 | 21 | void Mutex::Unlock() { uv_mutex_unlock(&mu_); } 22 | 23 | CondVar::CondVar(Mutex* mu) : mu_(mu) { uv_cond_init(&cv_); } 24 | 25 | CondVar::~CondVar() { uv_cond_destroy(&cv_); } 26 | 27 | void CondVar::Wait() { uv_cond_wait(&cv_, &mu_->mu_); } 28 | 29 | void CondVar::Signal() { uv_cond_signal(&cv_); } 30 | 31 | void CondVar::SignalAll() { uv_cond_broadcast(&cv_); } 32 | 33 | void InitOnce(OnceType* once, void (*initializer)()) { uv_once(once, initializer); } 34 | 35 | } // namespace port 36 | } // namespace leveldb 37 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 | void Merge(const Histogram& other); 20 | 21 | std::string ToString() const; 22 | 23 | private: 24 | double min_; 25 | double max_; 26 | double num_; 27 | double sum_; 28 | double sum_squares_; 29 | 30 | enum { kNumBuckets = 154 }; 31 | static const double kBucketLimit[kNumBuckets]; 32 | double buckets_[kNumBuckets]; 33 | 34 | double Median() const; 35 | double Percentile(double p) const; 36 | double Average() const; 37 | double StandardDeviation() const; 38 | }; 39 | 40 | } // namespace leveldb 41 | 42 | #endif // STORAGE_LEVELDB_UTIL_HISTOGRAM_H_ 43 | -------------------------------------------------------------------------------- /test/env-cleanup-hook-test.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const test = require('tape') 4 | const fork = require('child_process').fork 5 | const path = require('path') 6 | 7 | // Test env_cleanup_hook at several stages of a db lifetime 8 | addTest(['create']) 9 | addTest(['create', 'open']) 10 | addTest(['create', 'open', 'create-iterator']) 11 | addTest(['create', 'open', 'create-iterator', 'close']) 12 | addTest(['create', 'open', 'create-iterator', 'nexting']) 13 | addTest(['create', 'open', 'create-iterator', 'nexting', 'close']) 14 | addTest(['create', 'open', 'close']) 15 | addTest(['create', 'open-error']) 16 | 17 | function addTest (steps) { 18 | test(`cleanup on environment exit (${steps.join(', ')})`, function (t) { 19 | t.plan(3) 20 | 21 | const child = fork(path.join(__dirname, 'env-cleanup-hook.js'), steps) 22 | 23 | child.on('message', function (m) { 24 | t.is(m, steps[steps.length - 1], `got to step: ${m}`) 25 | child.disconnect() 26 | }) 27 | 28 | child.on('exit', function (code, sig) { 29 | t.is(code, 0, 'child exited normally') 30 | t.is(sig, null, 'not terminated due to signal') 31 | }) 32 | }) 33 | } 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright © 2012 Rod Vagg and the contributors to leveldown. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /test/chained-batch-gc-test.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const test = require('tape') 4 | const testCommon = require('./common') 5 | 6 | // When we have a chained batch object without a reference, V8 might GC it 7 | // before we get a chance to (asynchronously) write the batch. 8 | test('chained batch without ref does not get GCed before write', function (t) { 9 | t.plan(2) 10 | 11 | const db = testCommon.factory() 12 | 13 | db.open(function (err) { 14 | t.ifError(err, 'no open error') 15 | 16 | let batch = db.batch() 17 | 18 | for (let i = 0; i < 1e3; i++) { 19 | batch.put(String(i), 'value') 20 | } 21 | 22 | // The sync option makes the operation slower and thus more likely to 23 | // cause a segfault (if the batch were to be GC-ed before it is written). 24 | batch.write({ sync: true }, function (err) { 25 | t.ifError(err, 'no error from write()') 26 | }) 27 | 28 | // Remove reference 29 | batch = null 30 | 31 | if (global.gc) { 32 | // This is the reliable way to trigger GC (and the bug if it exists). 33 | // Useful for manual testing with "node --expose-gc". 34 | global.gc() 35 | } 36 | }) 37 | }) 38 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 | struct BlockContents; 15 | class Comparator; 16 | 17 | class Block { 18 | public: 19 | // Initialize the block with the specified contents. 20 | explicit Block(const BlockContents& contents); 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 | bool owned_; // Block owns data_[] 34 | 35 | // No copying allowed 36 | Block(const Block&); 37 | void operator=(const Block&); 38 | 39 | class Iter; 40 | }; 41 | 42 | } // namespace leveldb 43 | 44 | #endif // STORAGE_LEVELDB_TABLE_BLOCK_H_ 45 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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. 23 | // If no data is present in *iter, meta->file_size will be set to 24 | // zero, and no Table file will be produced. 25 | extern Status BuildTable(const std::string& dbname, 26 | Env* env, 27 | const Options& options, 28 | TableCache* table_cache, 29 | Iterator* iter, 30 | FileMetaData* meta); 31 | 32 | } // namespace leveldb 33 | 34 | #endif // STORAGE_LEVELDB_DB_BUILDER_H_ 35 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 | #include "port/thread_annotations.h" 10 | 11 | namespace leveldb { 12 | 13 | // Helper class that locks a mutex on construction and unlocks the mutex when 14 | // the destructor of the MutexLock object is invoked. 15 | // 16 | // Typical usage: 17 | // 18 | // void MyClass::MyMethod() { 19 | // MutexLock l(&mu_); // mu_ is an instance variable 20 | // ... some complex code, possibly with multiple return paths ... 21 | // } 22 | 23 | class SCOPED_LOCKABLE MutexLock { 24 | public: 25 | explicit MutexLock(port::Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu) 26 | : mu_(mu) { 27 | this->mu_->Lock(); 28 | } 29 | ~MutexLock() UNLOCK_FUNCTION() { this->mu_->Unlock(); } 30 | 31 | private: 32 | port::Mutex *const mu_; 33 | // No copying allowed 34 | MutexLock(const MutexLock&); 35 | void operator=(const MutexLock&); 36 | }; 37 | 38 | } // namespace leveldb 39 | 40 | 41 | #endif // STORAGE_LEVELDB_UTIL_MUTEXLOCK_H_ 42 | -------------------------------------------------------------------------------- /test/clear-gc-test.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const test = require('tape') 4 | const testCommon = require('./common') 5 | const sourceData = [] 6 | 7 | for (let i = 0; i < 1e3; i++) { 8 | sourceData.push({ 9 | type: 'put', 10 | key: i.toString(), 11 | value: Math.random().toString() 12 | }) 13 | } 14 | 15 | test('db without ref does not get GCed while clear() is in progress', function (t) { 16 | t.plan(4) 17 | 18 | let db = testCommon.factory() 19 | 20 | db.open(function (err) { 21 | t.ifError(err, 'no open error') 22 | 23 | // Insert test data 24 | db.batch(sourceData.slice(), function (err) { 25 | t.ifError(err, 'no batch error') 26 | 27 | // Start async work 28 | db.clear(function () { 29 | t.pass('got callback') 30 | 31 | // Give GC another chance to run, to rule out other issues. 32 | setImmediate(function () { 33 | if (global.gc) global.gc() 34 | t.pass() 35 | }) 36 | }) 37 | 38 | // Remove reference. The db should not get garbage collected 39 | // until after the clear() callback, thanks to a napi_ref. 40 | db = null 41 | 42 | // Useful for manual testing with "node --expose-gc". 43 | // The pending tap assertion may also allow GC to kick in. 44 | if (global.gc) global.gc() 45 | }) 46 | }) 47 | }) 48 | -------------------------------------------------------------------------------- /test/leak-tester.js: -------------------------------------------------------------------------------- 1 | const BUFFERS = false 2 | 3 | const testCommon = require('./common') 4 | const crypto = require('crypto') 5 | 6 | let putCount = 0 7 | let getCount = 0 8 | let rssBase 9 | 10 | function run () { 11 | let key = 'long key to test memory usage ' + String(Math.floor(Math.random() * 10000000)) 12 | 13 | if (BUFFERS) key = Buffer.from(key) 14 | 15 | db.get(key, function (err, value) { 16 | getCount++ 17 | 18 | if (err) { 19 | let putValue = crypto.randomBytes(1024) 20 | if (!BUFFERS) putValue = putValue.toString('hex') 21 | 22 | return db.put(key, putValue, function () { 23 | putCount++ 24 | process.nextTick(run) 25 | }) 26 | } 27 | 28 | process.nextTick(run) 29 | }) 30 | 31 | if (getCount % 1000 === 0) { 32 | if (typeof global.gc !== 'undefined') global.gc() 33 | console.log('getCount =', getCount, ', putCount = ', putCount, ', rss =', 34 | Math.round(process.memoryUsage().rss / rssBase * 100) + '%', 35 | Math.round(process.memoryUsage().rss / 1024 / 1024) + 'M', 36 | JSON.stringify([0, 1, 2, 3, 4, 5, 6].map(function (l) { 37 | return db.getProperty('leveldb.num-files-at-level' + l) 38 | }))) 39 | } 40 | } 41 | 42 | const db = testCommon.factory() 43 | 44 | db.open(function () { 45 | rssBase = process.memoryUsage().rss 46 | run() 47 | }) 48 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 | } // namespace leveldb 33 | 34 | #endif // STORAGE_LEVELDB_TABLE_TWO_LEVEL_ITERATOR_H_ 35 | -------------------------------------------------------------------------------- /iterator.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const util = require('util') 4 | const AbstractIterator = require('abstract-leveldown').AbstractIterator 5 | const binding = require('./binding') 6 | 7 | function Iterator (db, options) { 8 | AbstractIterator.call(this, db) 9 | 10 | this.context = binding.iterator_init(db.context, options) 11 | this.cache = null 12 | this.finished = false 13 | } 14 | 15 | util.inherits(Iterator, AbstractIterator) 16 | 17 | Iterator.prototype._seek = function (target) { 18 | if (target.length === 0) { 19 | throw new Error('cannot seek() to an empty target') 20 | } 21 | 22 | this.cache = null 23 | binding.iterator_seek(this.context, target) 24 | this.finished = false 25 | } 26 | 27 | Iterator.prototype._next = function (callback) { 28 | if (this.cache && this.cache.length) { 29 | process.nextTick(callback, null, this.cache.pop(), this.cache.pop()) 30 | } else if (this.finished) { 31 | process.nextTick(callback) 32 | } else { 33 | binding.iterator_next(this.context, (err, array, finished) => { 34 | if (err) return callback(err) 35 | 36 | this.cache = array 37 | this.finished = finished 38 | this._next(callback) 39 | }) 40 | } 41 | 42 | return this 43 | } 44 | 45 | Iterator.prototype._end = function (callback) { 46 | delete this.cache 47 | binding.iterator_end(this.context, callback) 48 | } 49 | 50 | module.exports = Iterator 51 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | on: [push, pull_request] 3 | permissions: 4 | contents: read 5 | jobs: 6 | test: 7 | strategy: 8 | matrix: 9 | # At the time of writing macos-latest is mac 10; we need 11 to build a universal binary. 10 | os: [ubuntu-latest, macos-11, windows-latest] 11 | node: [10, 12, 14] 12 | arch: [x86, x64] 13 | exclude: 14 | - { os: ubuntu-latest, arch: x86 } 15 | - { os: macos-11, arch: x86 } 16 | runs-on: ${{ matrix.os }} 17 | name: ${{ matrix.os }} / Node ${{ matrix.node }} ${{ matrix.arch }} 18 | steps: 19 | - name: Checkout 20 | uses: actions/checkout@v3 21 | with: 22 | submodules: recursive 23 | - name: Use node ${{ matrix.node }} 24 | uses: actions/setup-node@v3 25 | with: 26 | node-version: ${{ matrix.node }} 27 | architecture: ${{ matrix.arch }} 28 | - name: Install 29 | run: npm install 30 | - name: Test 31 | run: npm test 32 | - name: Coverage 33 | run: npm run coverage 34 | - name: Codecov 35 | uses: codecov/codecov-action@v3 36 | with: 37 | file: coverage/lcov.info 38 | - name: Test Electron 39 | if: ${{ matrix.node == '14' }} 40 | uses: GabrielBB/xvfb-action@v1 41 | with: 42 | run: npm run test-electron 43 | - name: Test GC 44 | run: npm run test-gc 45 | -------------------------------------------------------------------------------- /deps/leveldb/port-libuv/atomic_pointer_win.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // credit: https://groups.google.com/forum/#!msg/leveldb/VuECZMnsob4/F6pGPGaK-XwJ 5 | 6 | namespace leveldb { 7 | namespace port { 8 | 9 | class AtomicPointer { 10 | private: 11 | void* rep_; 12 | 13 | public: 14 | AtomicPointer () {} 15 | explicit AtomicPointer(void* v) { 16 | InterlockedExchangePointer(&rep_, v); 17 | } 18 | 19 | // Read and return the stored pointer with the guarantee that no 20 | // later memory access (read or write) by this thread can be 21 | // reordered ahead of this read. 22 | inline void* Acquire_Load() const { 23 | void* r; 24 | InterlockedExchangePointer(&r, rep_ ); 25 | return r; 26 | } 27 | 28 | // Set v as the stored pointer with the guarantee that no earlier 29 | // memory access (read or write) by this thread can be reordered 30 | // after this store. 31 | inline void Release_Store(void* v) { 32 | InterlockedExchangePointer(&rep_, v); 33 | } 34 | 35 | // Read the stored pointer with no ordering guarantees. 36 | inline void* NoBarrier_Load() const { 37 | void* r = reinterpret_cast(rep_); 38 | return r; 39 | } 40 | 41 | // Set va as the stored pointer with no ordering guarantees. 42 | inline void NoBarrier_Store(void* v) { 43 | rep_ = reinterpret_cast(v); 44 | } 45 | }; 46 | 47 | } // namespace port 48 | } // namespace leveldb 49 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 | } // namespace leveldb 43 | 44 | int main(int argc, char** argv) { 45 | return leveldb::test::RunAllTests(); 46 | } 47 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 | -------------------------------------------------------------------------------- /test/empty-range-option-test.js: -------------------------------------------------------------------------------- 1 | const test = require('tape') 2 | const concat = require('level-concat-iterator') 3 | const testCommon = require('./common') 4 | const rangeOptions = ['gt', 'gte', 'lt', 'lte'] 5 | 6 | test('empty range options are ignored', function (t) { 7 | const db = testCommon.factory() 8 | 9 | t.test('setup', function (t) { 10 | db.open(function (err) { 11 | t.ifError(err, 'no open error') 12 | 13 | db.batch() 14 | .put(Buffer.from([0]), 'value') 15 | .put(Buffer.from([126]), 'value') 16 | .write(t.end.bind(t)) 17 | }) 18 | }) 19 | 20 | rangeOptions.forEach(function (option) { 21 | t.test(option, function (t) { 22 | t.plan(8) 23 | 24 | concat(db.iterator({ [option]: Buffer.alloc(0) }), verifyBuffer) 25 | concat(db.iterator({ [option]: Buffer.alloc(0), keyAsBuffer: false }), verifyString) 26 | concat(db.iterator({ [option]: '' }), verifyBuffer) 27 | concat(db.iterator({ [option]: '', keyAsBuffer: false }), verifyString) 28 | 29 | function verifyBuffer (err, entries) { 30 | t.ifError(err, 'no concat error') 31 | t.same(entries.map(getKey), [Buffer.from([0]), Buffer.from([126])]) 32 | } 33 | 34 | function verifyString (err, entries) { 35 | t.ifError(err, 'no concat error') 36 | t.same(entries.map(getKey), ['\x00', '~']) 37 | } 38 | 39 | function getKey (entry) { 40 | return entry.key 41 | } 42 | }) 43 | }) 44 | 45 | t.test('teardown', function (t) { 46 | db.close(t.end.bind(t)) 47 | }) 48 | 49 | t.end() 50 | }) 51 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 | // The FALLTHROUGH_INTENDED macro can be used to annotate implicit fall-through 10 | // between switch labels. The real definition should be provided externally. 11 | // This one is a fallback version for unsupported compilers. 12 | #ifndef FALLTHROUGH_INTENDED 13 | #define FALLTHROUGH_INTENDED do { } while (0) 14 | #endif 15 | 16 | namespace leveldb { 17 | 18 | uint32_t Hash(const char* data, size_t n, uint32_t seed) { 19 | // Similar to murmur hash 20 | const uint32_t m = 0xc6a4a793; 21 | const uint32_t r = 24; 22 | const char* limit = data + n; 23 | uint32_t h = seed ^ (n * m); 24 | 25 | // Pick up four bytes at a time 26 | while (data + 4 <= limit) { 27 | uint32_t w = DecodeFixed32(data); 28 | data += 4; 29 | h += w; 30 | h *= m; 31 | h ^= (h >> 16); 32 | } 33 | 34 | // Pick up remaining bytes 35 | switch (limit - data) { 36 | case 3: 37 | h += static_cast(data[2]) << 16; 38 | FALLTHROUGH_INTENDED; 39 | case 2: 40 | h += static_cast(data[1]) << 8; 41 | FALLTHROUGH_INTENDED; 42 | case 1: 43 | h += static_cast(data[0]); 44 | h *= m; 45 | h ^= (h >> r); 46 | break; 47 | } 48 | return h; 49 | } 50 | 51 | 52 | } // namespace leveldb 53 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 | // Parse a human-readable number from "*in" into *value. On success, 36 | // advances "*in" past the consumed number and sets "*val" to the 37 | // numeric value. Otherwise, returns false and leaves *in in an 38 | // unspecified state. 39 | extern bool ConsumeDecimalNumber(Slice* in, uint64_t* val); 40 | 41 | } // namespace leveldb 42 | 43 | #endif // STORAGE_LEVELDB_UTIL_LOGGING_H_ 44 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/port/thread_annotations.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 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_THREAD_ANNOTATIONS_H_ 6 | #define STORAGE_LEVELDB_PORT_THREAD_ANNOTATIONS_H_ 7 | 8 | // Some environments provide custom macros to aid in static thread-safety 9 | // analysis. Provide empty definitions of such macros unless they are already 10 | // defined. 11 | 12 | #ifndef EXCLUSIVE_LOCKS_REQUIRED 13 | #define EXCLUSIVE_LOCKS_REQUIRED(...) 14 | #endif 15 | 16 | #ifndef SHARED_LOCKS_REQUIRED 17 | #define SHARED_LOCKS_REQUIRED(...) 18 | #endif 19 | 20 | #ifndef LOCKS_EXCLUDED 21 | #define LOCKS_EXCLUDED(...) 22 | #endif 23 | 24 | #ifndef LOCK_RETURNED 25 | #define LOCK_RETURNED(x) 26 | #endif 27 | 28 | #ifndef LOCKABLE 29 | #define LOCKABLE 30 | #endif 31 | 32 | #ifndef SCOPED_LOCKABLE 33 | #define SCOPED_LOCKABLE 34 | #endif 35 | 36 | #ifndef EXCLUSIVE_LOCK_FUNCTION 37 | #define EXCLUSIVE_LOCK_FUNCTION(...) 38 | #endif 39 | 40 | #ifndef SHARED_LOCK_FUNCTION 41 | #define SHARED_LOCK_FUNCTION(...) 42 | #endif 43 | 44 | #ifndef EXCLUSIVE_TRYLOCK_FUNCTION 45 | #define EXCLUSIVE_TRYLOCK_FUNCTION(...) 46 | #endif 47 | 48 | #ifndef SHARED_TRYLOCK_FUNCTION 49 | #define SHARED_TRYLOCK_FUNCTION(...) 50 | #endif 51 | 52 | #ifndef UNLOCK_FUNCTION 53 | #define UNLOCK_FUNCTION(...) 54 | #endif 55 | 56 | #ifndef NO_THREAD_SAFETY_ANALYSIS 57 | #define NO_THREAD_SAFETY_ANALYSIS 58 | #endif 59 | 60 | #endif // STORAGE_LEVELDB_PORT_THREAD_ANNOTATIONS_H_ 61 | -------------------------------------------------------------------------------- /test/env-cleanup-hook.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const testCommon = require('./common') 4 | 5 | function test (steps) { 6 | let step 7 | 8 | function nextStep () { 9 | step = steps.shift() || step 10 | return step 11 | } 12 | 13 | if (nextStep() !== 'create') { 14 | // Send a message triggering an environment exit 15 | // and indicating at which step we stopped. 16 | return process.send(step) 17 | } 18 | 19 | const db = testCommon.factory() 20 | 21 | if (nextStep() !== 'open') { 22 | if (nextStep() === 'open-error') { 23 | // If opening fails the cleanup hook should be a noop. 24 | db.open({ createIfMissing: false, errorIfExists: true }, function (err) { 25 | if (!err) throw new Error('Expected an open() error') 26 | }) 27 | } 28 | 29 | return process.send(step) 30 | } 31 | 32 | // Open the db, expected to be closed by the cleanup hook. 33 | db.open(function (err) { 34 | if (err) throw err 35 | 36 | if (nextStep() === 'create-iterator') { 37 | // Create an iterator, expected to be ended by the cleanup hook. 38 | const it = db.iterator() 39 | 40 | if (nextStep() === 'nexting') { 41 | // This async work should finish before the cleanup hook is called. 42 | it.next(function (err) { 43 | if (err) throw err 44 | }) 45 | } 46 | } 47 | 48 | if (nextStep() === 'close') { 49 | // Close the db, after which the cleanup hook is a noop. 50 | db.close(function (err) { 51 | if (err) throw err 52 | }) 53 | } 54 | 55 | process.send(step) 56 | }) 57 | } 58 | 59 | test(process.argv.slice(2)) 60 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 | } // namespace crc32c 43 | } // namespace leveldb 44 | 45 | #endif // STORAGE_LEVELDB_UTIL_CRC32C_H_ 46 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 | 11 | namespace leveldb { 12 | namespace port { 13 | 14 | static void PthreadCall(const char* label, int result) { 15 | if (result != 0) { 16 | fprintf(stderr, "pthread %s: %s\n", label, strerror(result)); 17 | abort(); 18 | } 19 | } 20 | 21 | Mutex::Mutex() { PthreadCall("init mutex", pthread_mutex_init(&mu_, NULL)); } 22 | 23 | Mutex::~Mutex() { PthreadCall("destroy mutex", pthread_mutex_destroy(&mu_)); } 24 | 25 | void Mutex::Lock() { PthreadCall("lock", pthread_mutex_lock(&mu_)); } 26 | 27 | void Mutex::Unlock() { PthreadCall("unlock", pthread_mutex_unlock(&mu_)); } 28 | 29 | CondVar::CondVar(Mutex* mu) 30 | : mu_(mu) { 31 | PthreadCall("init cv", pthread_cond_init(&cv_, NULL)); 32 | } 33 | 34 | CondVar::~CondVar() { PthreadCall("destroy cv", pthread_cond_destroy(&cv_)); } 35 | 36 | void CondVar::Wait() { 37 | PthreadCall("wait", pthread_cond_wait(&cv_, &mu_->mu_)); 38 | } 39 | 40 | void CondVar::Signal() { 41 | PthreadCall("signal", pthread_cond_signal(&cv_)); 42 | } 43 | 44 | void CondVar::SignalAll() { 45 | PthreadCall("broadcast", pthread_cond_broadcast(&cv_)); 46 | } 47 | 48 | void InitOnce(OnceType* once, void (*initializer)()) { 49 | PthreadCall("once", pthread_once(once, initializer)); 50 | } 51 | 52 | } // namespace port 53 | } // namespace leveldb 54 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 | size_t 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 | } // namespace test 51 | } // namespace leveldb 52 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 | 26 | // Create a writer that will append data to "*dest". 27 | // "*dest" must have initial length "dest_length". 28 | // "*dest" must remain live while this Writer is in use. 29 | Writer(WritableFile* dest, uint64_t dest_length); 30 | 31 | ~Writer(); 32 | 33 | Status AddRecord(const Slice& slice); 34 | 35 | private: 36 | WritableFile* dest_; 37 | int block_offset_; // Current offset in block 38 | 39 | // crc32c values for all supported record types. These are 40 | // pre-computed to reduce the overhead of computing the crc of the 41 | // record type stored in the header. 42 | uint32_t type_crc_[kMaxRecordType + 1]; 43 | 44 | Status EmitPhysicalRecord(RecordType type, const char* ptr, size_t length); 45 | 46 | // No copying allowed 47 | Writer(const Writer&); 48 | void operator=(const Writer&); 49 | }; 50 | 51 | } // namespace log 52 | } // namespace leveldb 53 | 54 | #endif // STORAGE_LEVELDB_DB_LOG_WRITER_H_ 55 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 "db/dbformat.h" 9 | #include "leveldb/write_batch.h" 10 | 11 | namespace leveldb { 12 | 13 | class MemTable; 14 | 15 | // WriteBatchInternal provides static methods for manipulating a 16 | // WriteBatch that we don't want in the public WriteBatch interface. 17 | class WriteBatchInternal { 18 | public: 19 | // Return the number of entries in the batch. 20 | static int Count(const WriteBatch* batch); 21 | 22 | // Set the count for the number of entries in the batch. 23 | static void SetCount(WriteBatch* batch, int n); 24 | 25 | // Return the sequence number for the start of this batch. 26 | static SequenceNumber Sequence(const WriteBatch* batch); 27 | 28 | // Store the specified number as the sequence number for the start of 29 | // this batch. 30 | static void SetSequence(WriteBatch* batch, SequenceNumber seq); 31 | 32 | static Slice Contents(const WriteBatch* batch) { 33 | return Slice(batch->rep_); 34 | } 35 | 36 | static size_t ByteSize(const WriteBatch* batch) { 37 | return batch->rep_.size(); 38 | } 39 | 40 | static void SetContents(WriteBatch* batch, const Slice& contents); 41 | 42 | static Status InsertInto(const WriteBatch* batch, MemTable* memtable); 43 | 44 | static void Append(WriteBatch* dst, const WriteBatch* src); 45 | }; 46 | 47 | } // namespace leveldb 48 | 49 | 50 | #endif // STORAGE_LEVELDB_DB_WRITE_BATCH_INTERNAL_H_ 51 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | We'd love to accept your code patches! However, before we can take them, we 4 | have to jump a couple of legal hurdles. 5 | 6 | ## Contributor License Agreements 7 | 8 | Please fill out either the individual or corporate Contributor License 9 | Agreement as appropriate. 10 | 11 | * If you are an individual writing original source code and you're sure you 12 | own the intellectual property, then sign an [individual CLA](https://developers.google.com/open-source/cla/individual). 13 | * If you work for a company that wants to allow you to contribute your work, 14 | then sign a [corporate CLA](https://developers.google.com/open-source/cla/corporate). 15 | 16 | Follow either of the two links above to access the appropriate CLA and 17 | instructions for how to sign and return it. 18 | 19 | ## Submitting a Patch 20 | 21 | 1. Sign the contributors license agreement above. 22 | 2. Decide which code you want to submit. A submission should be a set of changes 23 | that addresses one issue in the [issue tracker](https://github.com/google/leveldb/issues). 24 | Please don't mix more than one logical change per submission, because it makes 25 | the history hard to follow. If you want to make a change 26 | (e.g. add a sample or feature) that doesn't have a corresponding issue in the 27 | issue tracker, please create one. 28 | 3. **Submitting**: When you are ready to submit, send us a Pull Request. Be 29 | sure to include the issue number you fixed and the name you used to sign 30 | the CLA. 31 | 32 | ## Writing Code ## 33 | 34 | If your contribution contains code, please make sure that it follows 35 | [the style guide](http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml). 36 | Otherwise we will have to ask you to make changes, and that's no fun for anyone. 37 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/db/leveldbutil.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 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/dumpfile.h" 7 | #include "leveldb/env.h" 8 | #include "leveldb/status.h" 9 | 10 | namespace leveldb { 11 | namespace { 12 | 13 | class StdoutPrinter : public WritableFile { 14 | public: 15 | virtual Status Append(const Slice& data) { 16 | fwrite(data.data(), 1, data.size(), stdout); 17 | return Status::OK(); 18 | } 19 | virtual Status Close() { return Status::OK(); } 20 | virtual Status Flush() { return Status::OK(); } 21 | virtual Status Sync() { return Status::OK(); } 22 | }; 23 | 24 | bool HandleDumpCommand(Env* env, char** files, int num) { 25 | StdoutPrinter printer; 26 | bool ok = true; 27 | for (int i = 0; i < num; i++) { 28 | Status s = DumpFile(env, files[i], &printer); 29 | if (!s.ok()) { 30 | fprintf(stderr, "%s\n", s.ToString().c_str()); 31 | ok = false; 32 | } 33 | } 34 | return ok; 35 | } 36 | 37 | } // namespace 38 | } // namespace leveldb 39 | 40 | static void Usage() { 41 | fprintf( 42 | stderr, 43 | "Usage: leveldbutil command...\n" 44 | " dump files... -- dump contents of specified files\n" 45 | ); 46 | } 47 | 48 | int main(int argc, char** argv) { 49 | leveldb::Env* env = leveldb::Env::Default(); 50 | bool ok = true; 51 | if (argc < 2) { 52 | Usage(); 53 | ok = false; 54 | } else { 55 | std::string command = argv[1]; 56 | if (command == "dump") { 57 | ok = leveldb::HandleDumpCommand(env, argv+2, argc-2); 58 | } else { 59 | Usage(); 60 | ok = false; 61 | } 62 | } 63 | return (ok ? 0 : 1); 64 | } 65 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/util/hash_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/hash.h" 6 | #include "util/testharness.h" 7 | 8 | namespace leveldb { 9 | 10 | class HASH { }; 11 | 12 | TEST(HASH, SignedUnsignedIssue) { 13 | const unsigned char data1[1] = {0x62}; 14 | const unsigned char data2[2] = {0xc3, 0x97}; 15 | const unsigned char data3[3] = {0xe2, 0x99, 0xa5}; 16 | const unsigned char data4[4] = {0xe1, 0x80, 0xb9, 0x32}; 17 | const unsigned char data5[48] = { 18 | 0x01, 0xc0, 0x00, 0x00, 19 | 0x00, 0x00, 0x00, 0x00, 20 | 0x00, 0x00, 0x00, 0x00, 21 | 0x00, 0x00, 0x00, 0x00, 22 | 0x14, 0x00, 0x00, 0x00, 23 | 0x00, 0x00, 0x04, 0x00, 24 | 0x00, 0x00, 0x00, 0x14, 25 | 0x00, 0x00, 0x00, 0x18, 26 | 0x28, 0x00, 0x00, 0x00, 27 | 0x00, 0x00, 0x00, 0x00, 28 | 0x02, 0x00, 0x00, 0x00, 29 | 0x00, 0x00, 0x00, 0x00, 30 | }; 31 | 32 | ASSERT_EQ(Hash(0, 0, 0xbc9f1d34), 0xbc9f1d34); 33 | ASSERT_EQ( 34 | Hash(reinterpret_cast(data1), sizeof(data1), 0xbc9f1d34), 35 | 0xef1345c4); 36 | ASSERT_EQ( 37 | Hash(reinterpret_cast(data2), sizeof(data2), 0xbc9f1d34), 38 | 0x5b663814); 39 | ASSERT_EQ( 40 | Hash(reinterpret_cast(data3), sizeof(data3), 0xbc9f1d34), 41 | 0x323c078f); 42 | ASSERT_EQ( 43 | Hash(reinterpret_cast(data4), sizeof(data4), 0xbc9f1d34), 44 | 0xed21633a); 45 | ASSERT_EQ( 46 | Hash(reinterpret_cast(data5), sizeof(data5), 0x12345678), 47 | 0xf333dabb); 48 | } 49 | 50 | } // namespace leveldb 51 | 52 | int main(int argc, char** argv) { 53 | return leveldb::test::RunAllTests(); 54 | } 55 | -------------------------------------------------------------------------------- /test/compact-range-test.js: -------------------------------------------------------------------------------- 1 | const test = require('tape') 2 | const testCommon = require('./common') 3 | 4 | let db 5 | 6 | test('setUp common', testCommon.setUp) 7 | 8 | test('setUp db', function (t) { 9 | db = testCommon.factory() 10 | db.open(t.end.bind(t)) 11 | }) 12 | 13 | test('test compactRange() frees disk space after key deletion', function (t) { 14 | const key1 = '000000' 15 | const key2 = '000001' 16 | const val1 = Buffer.allocUnsafe(64).fill(1) 17 | const val2 = Buffer.allocUnsafe(64).fill(1) 18 | 19 | db.batch().put(key1, val1).put(key2, val2).write(function (err) { 20 | t.ifError(err, 'no batch put error') 21 | 22 | db.compactRange(key1, key2, function (err) { 23 | t.ifError(err, 'no compactRange1 error') 24 | 25 | db.approximateSize('0', 'z', function (err, sizeAfterPuts) { 26 | t.error(err, 'no approximateSize1 error') 27 | 28 | db.batch().del(key1).del(key2).write(function (err) { 29 | t.ifError(err, 'no batch del error') 30 | 31 | db.compactRange(key1, key2, function (err) { 32 | t.ifError(err, 'no compactRange2 error') 33 | 34 | db.approximateSize('0', 'z', function (err, sizeAfterCompact) { 35 | t.error(err, 'no approximateSize2 error') 36 | t.ok(sizeAfterCompact < sizeAfterPuts) 37 | t.end() 38 | }) 39 | }) 40 | }) 41 | }) 42 | }) 43 | }) 44 | }) 45 | 46 | test('test compactRange() serializes start and end', function (t) { 47 | t.plan(3) 48 | 49 | const clone = Object.create(db) 50 | let count = 0 51 | 52 | clone._serializeKey = function (key) { 53 | t.is(key, count++) 54 | return db._serializeKey(key) 55 | } 56 | 57 | clone.compactRange(0, 1, function (err) { 58 | t.ifError(err, 'no compactRange error') 59 | }) 60 | }) 61 | 62 | test('tearDown', function (t) { 63 | db.close(testCommon.tearDown.bind(null, t)) 64 | }) 65 | -------------------------------------------------------------------------------- /test/getproperty-test.js: -------------------------------------------------------------------------------- 1 | const test = require('tape') 2 | const testCommon = require('./common') 3 | 4 | let db 5 | 6 | test('setUp common', testCommon.setUp) 7 | 8 | test('setUp db', function (t) { 9 | db = testCommon.factory() 10 | db.open(t.end.bind(t)) 11 | }) 12 | 13 | test('test argument-less getProperty() throws', function (t) { 14 | t.throws(db.getProperty.bind(db), { 15 | name: 'Error', 16 | message: 'getProperty() requires a valid `property` argument' 17 | }, 'no-arg getProperty() throws') 18 | t.end() 19 | }) 20 | 21 | test('test non-string getProperty() throws', function (t) { 22 | t.throws(db.getProperty.bind(db, {}), { 23 | name: 'Error', 24 | message: 'getProperty() requires a valid `property` argument' 25 | }, 'no-arg getProperty() throws') 26 | t.end() 27 | }) 28 | 29 | test('test invalid getProperty() returns empty string', function (t) { 30 | t.equal(db.getProperty('foo'), '', 'invalid property') 31 | t.equal(db.getProperty('leveldb.foo'), '', 'invalid leveldb.* property') 32 | t.end() 33 | }) 34 | 35 | test('test invalid getProperty("leveldb.num-files-at-levelN") returns numbers', function (t) { 36 | for (let i = 0; i < 7; i++) { 37 | t.equal(db.getProperty('leveldb.num-files-at-level' + i), 38 | '0', '"leveldb.num-files-at-levelN" === "0"') 39 | } 40 | t.end() 41 | }) 42 | 43 | test('test invalid getProperty("leveldb.stats")', function (t) { 44 | t.ok(db.getProperty('leveldb.stats').split('\n').length > 3, 'leveldb.stats has > 3 newlines') 45 | t.end() 46 | }) 47 | 48 | test('test invalid getProperty("leveldb.sstables")', function (t) { 49 | const expected = [0, 1, 2, 3, 4, 5, 6].map(function (l) { 50 | return '--- level ' + l + ' ---' 51 | }).join('\n') + '\n' 52 | t.equal(db.getProperty('leveldb.sstables'), expected, 'leveldb.sstables') 53 | t.end() 54 | }) 55 | 56 | test('tearDown', function (t) { 57 | db.close(testCommon.tearDown.bind(null, t)) 58 | }) 59 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/issues/issue200_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 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 | // Test for issue 200: when iterator switches direction from backward 6 | // to forward, the current key can be yielded unexpectedly if a new 7 | // mutation has been added just before the current key. 8 | 9 | #include "leveldb/db.h" 10 | #include "util/testharness.h" 11 | 12 | namespace leveldb { 13 | 14 | class Issue200 { }; 15 | 16 | TEST(Issue200, Test) { 17 | // Get rid of any state from an old run. 18 | std::string dbpath = test::TmpDir() + "/leveldb_issue200_test"; 19 | DestroyDB(dbpath, Options()); 20 | 21 | DB *db; 22 | Options options; 23 | options.create_if_missing = true; 24 | ASSERT_OK(DB::Open(options, dbpath, &db)); 25 | 26 | WriteOptions write_options; 27 | ASSERT_OK(db->Put(write_options, "1", "b")); 28 | ASSERT_OK(db->Put(write_options, "2", "c")); 29 | ASSERT_OK(db->Put(write_options, "3", "d")); 30 | ASSERT_OK(db->Put(write_options, "4", "e")); 31 | ASSERT_OK(db->Put(write_options, "5", "f")); 32 | 33 | ReadOptions read_options; 34 | Iterator *iter = db->NewIterator(read_options); 35 | 36 | // Add an element that should not be reflected in the iterator. 37 | ASSERT_OK(db->Put(write_options, "25", "cd")); 38 | 39 | iter->Seek("5"); 40 | ASSERT_EQ(iter->key().ToString(), "5"); 41 | iter->Prev(); 42 | ASSERT_EQ(iter->key().ToString(), "4"); 43 | iter->Prev(); 44 | ASSERT_EQ(iter->key().ToString(), "3"); 45 | iter->Next(); 46 | ASSERT_EQ(iter->key().ToString(), "4"); 47 | iter->Next(); 48 | ASSERT_EQ(iter->key().ToString(), "5"); 49 | 50 | delete iter; 51 | delete db; 52 | DestroyDB(dbpath, options); 53 | } 54 | 55 | } // namespace leveldb 56 | 57 | int main(int argc, char** argv) { 58 | return leveldb::test::RunAllTests(); 59 | } 60 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 "db/dbformat.h" 9 | #include "leveldb/db.h" 10 | 11 | namespace leveldb { 12 | 13 | class SnapshotList; 14 | 15 | // Snapshots are kept in a doubly-linked list in the DB. 16 | // Each SnapshotImpl corresponds to a particular sequence number. 17 | class SnapshotImpl : public Snapshot { 18 | public: 19 | SequenceNumber number_; // const after creation 20 | 21 | private: 22 | friend class SnapshotList; 23 | 24 | // SnapshotImpl is kept in a doubly-linked circular list 25 | SnapshotImpl* prev_; 26 | SnapshotImpl* next_; 27 | 28 | SnapshotList* list_; // just for sanity checks 29 | }; 30 | 31 | class SnapshotList { 32 | public: 33 | SnapshotList() { 34 | list_.prev_ = &list_; 35 | list_.next_ = &list_; 36 | } 37 | 38 | bool empty() const { return list_.next_ == &list_; } 39 | SnapshotImpl* oldest() const { assert(!empty()); return list_.next_; } 40 | SnapshotImpl* newest() const { assert(!empty()); return list_.prev_; } 41 | 42 | const SnapshotImpl* New(SequenceNumber seq) { 43 | SnapshotImpl* s = new SnapshotImpl; 44 | s->number_ = seq; 45 | s->list_ = this; 46 | s->next_ = &list_; 47 | s->prev_ = list_.prev_; 48 | s->prev_->next_ = s; 49 | s->next_->prev_ = s; 50 | return s; 51 | } 52 | 53 | void Delete(const SnapshotImpl* s) { 54 | assert(s->list_ == this); 55 | s->prev_->next_ = s->next_; 56 | s->next_->prev_ = s->prev_; 57 | delete s; 58 | } 59 | 60 | private: 61 | // Dummy head of doubly-linked list of snapshots 62 | SnapshotImpl list_; 63 | }; 64 | 65 | } // namespace leveldb 66 | 67 | #endif // STORAGE_LEVELDB_DB_SNAPSHOT_H_ 68 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 (size_t 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 (size_t i = 0; i < allocated.size(); i++) { 55 | size_t num_bytes = allocated[i].first; 56 | const char* p = allocated[i].second; 57 | for (size_t 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 | } // namespace leveldb 65 | 66 | int main(int argc, char** argv) { 67 | return leveldb::test::RunAllTests(); 68 | } 69 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 | 7 | namespace leveldb { 8 | 9 | Iterator::Iterator() { 10 | cleanup_.function = NULL; 11 | cleanup_.next = NULL; 12 | } 13 | 14 | Iterator::~Iterator() { 15 | if (cleanup_.function != NULL) { 16 | (*cleanup_.function)(cleanup_.arg1, cleanup_.arg2); 17 | for (Cleanup* c = cleanup_.next; c != NULL; ) { 18 | (*c->function)(c->arg1, c->arg2); 19 | Cleanup* next = c->next; 20 | delete c; 21 | c = next; 22 | } 23 | } 24 | } 25 | 26 | void Iterator::RegisterCleanup(CleanupFunction func, void* arg1, void* arg2) { 27 | assert(func != NULL); 28 | Cleanup* c; 29 | if (cleanup_.function == NULL) { 30 | c = &cleanup_; 31 | } else { 32 | c = new Cleanup; 33 | c->next = cleanup_.next; 34 | cleanup_.next = c; 35 | } 36 | c->function = func; 37 | c->arg1 = arg1; 38 | c->arg2 = arg2; 39 | } 40 | 41 | namespace { 42 | class EmptyIterator : public Iterator { 43 | public: 44 | EmptyIterator(const Status& s) : status_(s) { } 45 | virtual bool Valid() const { return false; } 46 | virtual void Seek(const Slice& target) { } 47 | virtual void SeekToFirst() { } 48 | virtual void SeekToLast() { } 49 | virtual void Next() { assert(false); } 50 | virtual void Prev() { assert(false); } 51 | Slice key() const { assert(false); return Slice(); } 52 | Slice value() const { assert(false); return Slice(); } 53 | virtual Status status() const { return status_; } 54 | private: 55 | Status status_; 56 | }; 57 | } // namespace 58 | 59 | Iterator* NewEmptyIterator() { 60 | return new EmptyIterator(Status::OK()); 61 | } 62 | 63 | Iterator* NewErrorIterator(const Status& status) { 64 | return new EmptyIterator(status); 65 | } 66 | 67 | } // namespace leveldb 68 | -------------------------------------------------------------------------------- /binding.gyp: -------------------------------------------------------------------------------- 1 | { 2 | "targets": [{ 3 | "target_name": "leveldown", 4 | "conditions": [ 5 | ["OS == 'win'", { 6 | "defines": [ 7 | "_HAS_EXCEPTIONS=0" 8 | ], 9 | "msvs_settings": { 10 | "VCCLCompilerTool": { 11 | "RuntimeTypeInfo": "false", 12 | "EnableFunctionLevelLinking": "true", 13 | "ExceptionHandling": "2", 14 | "DisableSpecificWarnings": [ "4355", "4530" ,"4267", "4244", "4506" ] 15 | } 16 | } 17 | }], 18 | ["OS == 'linux'", { 19 | "cflags": [], 20 | "cflags!": [ "-fno-tree-vrp"] 21 | }], 22 | ["OS == 'mac'", { 23 | "cflags+": ["-fvisibility=hidden"], 24 | "xcode_settings": { 25 | # -fvisibility=hidden 26 | "GCC_SYMBOLS_PRIVATE_EXTERN": "YES", 27 | 28 | # Set minimum target version because we're building on newer 29 | # Same as https://github.com/nodejs/node/blob/v10.0.0/common.gypi#L416 30 | "MACOSX_DEPLOYMENT_TARGET": "10.7", 31 | 32 | # Build universal binary to support M1 (Apple silicon) 33 | "OTHER_CFLAGS": [ 34 | "-arch x86_64", 35 | "-arch arm64" 36 | ], 37 | "OTHER_LDFLAGS": [ 38 | "-arch x86_64", 39 | "-arch arm64" 40 | ] 41 | } 42 | }], 43 | ["OS == 'android'", { 44 | "cflags": [ "-fPIC" ], 45 | "ldflags": [ "-fPIC" ], 46 | "cflags!": [ 47 | "-fno-tree-vrp", 48 | "-mfloat-abi=hard", 49 | "-fPIE" 50 | ], 51 | "ldflags!": [ "-fPIE" ] 52 | }], 53 | ["target_arch == 'arm'", { 54 | "cflags": [ "-mfloat-abi=hard" ] 55 | }] 56 | ], 57 | "dependencies": [ 58 | "<(module_root_dir)/deps/leveldb/leveldb.gyp:leveldb" 59 | ], 60 | "include_dirs" : [ 61 | " 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 called 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 | } // namespace leveldb 56 | 57 | #endif // STORAGE_LEVELDB_TABLE_BLOCK_BUILDER_H_ 58 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 | #include 10 | #include 11 | 12 | namespace leveldb { 13 | namespace test { 14 | 15 | namespace { 16 | struct Test { 17 | const char* base; 18 | const char* name; 19 | void (*func)(); 20 | }; 21 | std::vector* tests; 22 | } 23 | 24 | bool RegisterTest(const char* base, const char* name, void (*func)()) { 25 | if (tests == NULL) { 26 | tests = new std::vector; 27 | } 28 | Test t; 29 | t.base = base; 30 | t.name = name; 31 | t.func = func; 32 | tests->push_back(t); 33 | return true; 34 | } 35 | 36 | int RunAllTests() { 37 | const char* matcher = getenv("LEVELDB_TESTS"); 38 | 39 | int num = 0; 40 | if (tests != NULL) { 41 | for (size_t i = 0; i < tests->size(); i++) { 42 | const Test& t = (*tests)[i]; 43 | if (matcher != NULL) { 44 | std::string name = t.base; 45 | name.push_back('.'); 46 | name.append(t.name); 47 | if (strstr(name.c_str(), matcher) == NULL) { 48 | continue; 49 | } 50 | } 51 | fprintf(stderr, "==== Test %s.%s\n", t.base, t.name); 52 | (*t.func)(); 53 | ++num; 54 | } 55 | } 56 | fprintf(stderr, "==== PASSED %d tests\n", num); 57 | return 0; 58 | } 59 | 60 | std::string TmpDir() { 61 | std::string dir; 62 | Status s = Env::Default()->GetTestDirectory(&dir); 63 | ASSERT_TRUE(s.ok()) << s.ToString(); 64 | return dir; 65 | } 66 | 67 | int RandomSeed() { 68 | const char* env = getenv("TEST_RANDOM_SEED"); 69 | int result = (env != NULL ? atoi(env) : 301); 70 | if (result <= 0) { 71 | result = 301; 72 | } 73 | return result; 74 | } 75 | 76 | } // namespace test 77 | } // namespace leveldb 78 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 ConsumeDecimalNumber(Slice* in, uint64_t* val) { 49 | uint64_t v = 0; 50 | int digits = 0; 51 | while (!in->empty()) { 52 | char c = (*in)[0]; 53 | if (c >= '0' && c <= '9') { 54 | ++digits; 55 | const int delta = (c - '0'); 56 | static const uint64_t kMaxUint64 = ~static_cast(0); 57 | if (v > kMaxUint64/10 || 58 | (v == kMaxUint64/10 && delta > kMaxUint64%10)) { 59 | // Overflow 60 | return false; 61 | } 62 | v = (v * 10) + delta; 63 | in->remove_prefix(1); 64 | } else { 65 | break; 66 | } 67 | } 68 | *val = v; 69 | return (digits > 0); 70 | } 71 | 72 | } // namespace leveldb 73 | -------------------------------------------------------------------------------- /test/leak-tester-batch.js: -------------------------------------------------------------------------------- 1 | const BUFFERS = false 2 | const CHAINED = false 3 | 4 | const testCommon = require('./common') 5 | const crypto = require('crypto') 6 | const assert = require('assert') 7 | 8 | let writeCount = 0 9 | let rssBase 10 | 11 | function print () { 12 | if (writeCount % 100 === 0) { 13 | if (typeof global.gc !== 'undefined') global.gc() 14 | 15 | console.log( 16 | 'writeCount =', writeCount, ', rss =', 17 | Math.round(process.memoryUsage().rss / rssBase * 100) + '%', 18 | Math.round(process.memoryUsage().rss / 1024 / 1024) + 'M', 19 | JSON.stringify([0, 1, 2, 3, 4, 5, 6].map(function (l) { 20 | return db.getProperty('leveldb.num-files-at-level' + l) 21 | })) 22 | ) 23 | } 24 | } 25 | 26 | const run = CHAINED 27 | ? function () { 28 | const batch = db.batch() 29 | 30 | for (let i = 0; i < 100; i++) { 31 | let key = 'long key to test memory usage ' + String(Math.floor(Math.random() * 10000000)) 32 | if (BUFFERS) key = Buffer.from(key) 33 | let value = crypto.randomBytes(1024) 34 | if (!BUFFERS) value = value.toString('hex') 35 | batch.put(key, value) 36 | } 37 | 38 | batch.write(function (err) { 39 | assert(!err) 40 | process.nextTick(run) 41 | }) 42 | 43 | writeCount++ 44 | print() 45 | } 46 | : function () { 47 | const batch = [] 48 | 49 | for (let i = 0; i < 100; i++) { 50 | let key = 'long key to test memory usage ' + String(Math.floor(Math.random() * 10000000)) 51 | if (BUFFERS) key = Buffer.from(key) 52 | let value = crypto.randomBytes(1024) 53 | if (!BUFFERS) value = value.toString('hex') 54 | batch.push({ type: 'put', key: key, value: value }) 55 | } 56 | 57 | db.batch(batch, function (err) { 58 | assert(!err) 59 | process.nextTick(run) 60 | }) 61 | 62 | writeCount++ 63 | print() 64 | } 65 | 66 | const db = testCommon.factory() 67 | 68 | db.open(function () { 69 | rssBase = process.memoryUsage().rss 70 | run() 71 | }) 72 | -------------------------------------------------------------------------------- /deps/leveldb/port-libuv/uv_condvar.h: -------------------------------------------------------------------------------- 1 | // uv_cond_* backport 2 | // Lifted from the Node 0.9 version of libuv for Node 0.8 compatibility 3 | // https://github.com/joyent/libuv/ 4 | 5 | // libuv copyright notice: 6 | 7 | /* Copyright Joyent, Inc. and other Node contributors. All rights reserved. 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to 11 | * deal in the Software without restriction, including without limitation the 12 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 13 | * sell copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in 17 | * all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 25 | * IN THE SOFTWARE. 26 | */ 27 | 28 | #ifndef LEVELDB_PORT_LIBUV_CONVAR_H_ 29 | #define LEVELDB_PORT_LIBUV_CONVAR_H_ 30 | 31 | #include 32 | 33 | #ifdef LDB_UV_POSIX 34 | typedef pthread_cond_t ldb_uv_cond_t; 35 | #endif 36 | 37 | 38 | UV_EXTERN int ldb_uv_cond_init(ldb_uv_cond_t* cond); 39 | UV_EXTERN void ldb_uv_cond_destroy(ldb_uv_cond_t* cond); 40 | UV_EXTERN void ldb_uv_cond_signal(ldb_uv_cond_t* cond); 41 | UV_EXTERN void ldb_uv_cond_broadcast(ldb_uv_cond_t* cond); 42 | UV_EXTERN void ldb_uv_cond_wait(ldb_uv_cond_t* cond, uv_mutex_t* mutex); 43 | UV_EXTERN int ldb_uv_cond_timedwait(ldb_uv_cond_t* cond, uv_mutex_t* mutex, uint64_t timeout); 44 | 45 | #endif // LEVELDB_PORT_LIBUV_CONVAR_H_ 46 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 | } // namespace crc32c 68 | } // namespace leveldb 69 | 70 | int main(int argc, char** argv) { 71 | return leveldb::test::RunAllTests(); 72 | } 73 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 | #include "port/port.h" 13 | 14 | namespace leveldb { 15 | 16 | class Arena { 17 | public: 18 | Arena(); 19 | ~Arena(); 20 | 21 | // Return a pointer to a newly allocated memory block of "bytes" bytes. 22 | char* Allocate(size_t bytes); 23 | 24 | // Allocate memory with the normal alignment guarantees provided by malloc 25 | char* AllocateAligned(size_t bytes); 26 | 27 | // Returns an estimate of the total memory usage of data allocated 28 | // by the arena. 29 | size_t MemoryUsage() const { 30 | return reinterpret_cast(memory_usage_.NoBarrier_Load()); 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 | // Total memory usage of the arena. 45 | port::AtomicPointer memory_usage_; 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 | } // namespace leveldb 67 | 68 | #endif // STORAGE_LEVELDB_UTIL_ARENA_H_ 69 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 | } // namespace leveldb 63 | 64 | #endif // STORAGE_LEVELDB_INCLUDE_WRITE_BATCH_H_ 65 | -------------------------------------------------------------------------------- /deps/leveldb/port-libuv/win_logger.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 "win_logger.h" 6 | 7 | #include 8 | 9 | namespace leveldb { 10 | 11 | void WinLogger::Logv(const char* format, va_list ap) { 12 | const uint64_t thread_id = static_cast(::GetCurrentThreadId()); 13 | 14 | // We try twice: the first time with a fixed-size stack allocated buffer, 15 | // and the second time with a much larger dynamically allocated buffer. 16 | char buffer[500]; 17 | 18 | for (int iter = 0; iter < 2; iter++) { 19 | char* base; 20 | int bufsize; 21 | if (iter == 0) { 22 | bufsize = sizeof(buffer); 23 | base = buffer; 24 | } else { 25 | bufsize = 30000; 26 | base = new char[bufsize]; 27 | } 28 | 29 | char* p = base; 30 | char* limit = base + bufsize; 31 | 32 | SYSTEMTIME st; 33 | 34 | // GetSystemTime returns UTC time, we want local time! 35 | ::GetLocalTime(&st); 36 | 37 | p += _snprintf_s(p, limit - p, _TRUNCATE, 38 | "%04d/%02d/%02d-%02d:%02d:%02d.%03d %llx ", 39 | st.wYear, 40 | st.wMonth, 41 | st.wDay, 42 | st.wHour, 43 | st.wMinute, 44 | st.wSecond, 45 | st.wMilliseconds, 46 | static_cast(thread_id)); 47 | 48 | // Print the message 49 | if (p < limit) { 50 | va_list backup_ap = ap; 51 | p += vsnprintf(p, limit - p, format, backup_ap); 52 | va_end(backup_ap); 53 | } 54 | 55 | // Truncate to available space if necessary 56 | if (p >= limit) { 57 | if (iter == 0) { 58 | continue; // Try again with larger buffer 59 | } else { 60 | p = limit - 1; 61 | } 62 | } 63 | 64 | // Add newline if necessary 65 | if (p == base || p[-1] != '\n') { 66 | *p++ = '\n'; 67 | } 68 | 69 | assert(p <= limit); 70 | fwrite(base, 1, p - base, file_); 71 | fflush(file_); 72 | if (base != buffer) { 73 | delete[] base; 74 | } 75 | break; 76 | } 77 | } 78 | 79 | } -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 | } // namespace leveldb 76 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 | // If a seek to internal key "k" in specified file finds an entry, 39 | // call (*handle_result)(arg, found_key, found_value). 40 | Status Get(const ReadOptions& options, 41 | uint64_t file_number, 42 | uint64_t file_size, 43 | const Slice& k, 44 | void* arg, 45 | void (*handle_result)(void*, const Slice&, const Slice&)); 46 | 47 | // Evict any entry for the specified file number 48 | void Evict(uint64_t file_number); 49 | 50 | private: 51 | Env* const env_; 52 | const std::string dbname_; 53 | const Options* options_; 54 | Cache* cache_; 55 | 56 | Status FindTable(uint64_t file_number, uint64_t file_size, Cache::Handle**); 57 | }; 58 | 59 | } // namespace leveldb 60 | 61 | #endif // STORAGE_LEVELDB_DB_TABLE_CACHE_H_ 62 | -------------------------------------------------------------------------------- /test/iterator-gc-test.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const test = require('tape') 4 | const collectEntries = require('level-concat-iterator') 5 | const testCommon = require('./common') 6 | const sourceData = [] 7 | 8 | for (let i = 0; i < 1e3; i++) { 9 | sourceData.push({ 10 | type: 'put', 11 | key: i.toString(), 12 | value: Math.random().toString() 13 | }) 14 | } 15 | 16 | test('setUp', testCommon.setUp) 17 | 18 | // When you have a database open with an active iterator, but no references to 19 | // the db, V8 will GC the database and you'll get an failed assert from LevelDB. 20 | test('db without ref does not get GCed while iterating', function (t) { 21 | t.plan(6) 22 | 23 | let db = testCommon.factory() 24 | 25 | db.open(function (err) { 26 | t.ifError(err, 'no open error') 27 | 28 | // Insert test data 29 | db.batch(sourceData.slice(), function (err) { 30 | t.ifError(err, 'no batch error') 31 | 32 | // Set highWaterMark to 0 so that we don't preemptively fetch. 33 | const it = db.iterator({ highWaterMark: 0 }) 34 | 35 | // Remove reference 36 | db = null 37 | 38 | if (global.gc) { 39 | // This is the reliable way to trigger GC (and the bug if it exists). 40 | // Useful for manual testing with "node --expose-gc". 41 | global.gc() 42 | iterate(it) 43 | } else { 44 | // But a timeout usually also allows GC to kick in. If not, the time 45 | // between iterator ticks might. That's when "highWaterMark: 0" helps. 46 | setTimeout(iterate.bind(null, it), 1000) 47 | } 48 | }) 49 | }) 50 | 51 | function iterate (it) { 52 | // No reference to db here, could be GCed. It shouldn't.. 53 | collectEntries(it, function (err, entries) { 54 | t.ifError(err, 'no iterator error') 55 | t.is(entries.length, sourceData.length, 'got data') 56 | 57 | // Because we also have a reference on the iterator. That's the fix. 58 | t.ok(it.db, 'abstract iterator has reference to db') 59 | 60 | // Which as luck would have it, also allows us to properly end this test. 61 | it.db.close(function (err) { 62 | t.ifError(err, 'no close error') 63 | }) 64 | }) 65 | } 66 | }) 67 | 68 | test('tearDown', testCommon.tearDown) 69 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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() : memory_usage_(0) { 13 | alloc_ptr_ = NULL; // First allocation will allocate a block 14 | alloc_bytes_remaining_ = 0; 15 | } 16 | 17 | Arena::~Arena() { 18 | for (size_t i = 0; i < blocks_.size(); i++) { 19 | delete[] blocks_[i]; 20 | } 21 | } 22 | 23 | char* Arena::AllocateFallback(size_t bytes) { 24 | if (bytes > kBlockSize / 4) { 25 | // Object is more than a quarter of our block size. Allocate it separately 26 | // to avoid wasting too much space in leftover bytes. 27 | char* result = AllocateNewBlock(bytes); 28 | return result; 29 | } 30 | 31 | // We waste the remaining space in the current block. 32 | alloc_ptr_ = AllocateNewBlock(kBlockSize); 33 | alloc_bytes_remaining_ = kBlockSize; 34 | 35 | char* result = alloc_ptr_; 36 | alloc_ptr_ += bytes; 37 | alloc_bytes_remaining_ -= bytes; 38 | return result; 39 | } 40 | 41 | char* Arena::AllocateAligned(size_t bytes) { 42 | const int align = (sizeof(void*) > 8) ? sizeof(void*) : 8; 43 | assert((align & (align-1)) == 0); // Pointer size should be a power of 2 44 | size_t current_mod = reinterpret_cast(alloc_ptr_) & (align-1); 45 | size_t slop = (current_mod == 0 ? 0 : align - current_mod); 46 | size_t needed = bytes + slop; 47 | char* result; 48 | if (needed <= alloc_bytes_remaining_) { 49 | result = alloc_ptr_ + slop; 50 | alloc_ptr_ += needed; 51 | alloc_bytes_remaining_ -= needed; 52 | } else { 53 | // AllocateFallback always returned aligned memory 54 | result = AllocateFallback(bytes); 55 | } 56 | assert((reinterpret_cast(result) & (align-1)) == 0); 57 | return result; 58 | } 59 | 60 | char* Arena::AllocateNewBlock(size_t block_bytes) { 61 | char* result = new char[block_bytes]; 62 | blocks_.push_back(result); 63 | memory_usage_.NoBarrier_Store( 64 | reinterpret_cast(MemoryUsage() + block_bytes + sizeof(char*))); 65 | return result; 66 | } 67 | 68 | } // namespace leveldb 69 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 | size_t 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 | virtual Status NewAppendableFile(const std::string& fname, 50 | WritableFile** result) { 51 | if (writable_file_error_) { 52 | ++num_writable_file_errors_; 53 | *result = NULL; 54 | return Status::IOError(fname, "fake error"); 55 | } 56 | return target()->NewAppendableFile(fname, result); 57 | } 58 | }; 59 | 60 | } // namespace test 61 | } // namespace leveldb 62 | 63 | #endif // STORAGE_LEVELDB_UTIL_TESTUTIL_H_ 64 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 | #include "leveldb/iterator.h" 9 | #include "leveldb/slice.h" 10 | 11 | namespace leveldb { 12 | 13 | // A internal wrapper class with an interface similar to Iterator that 14 | // caches the valid() and key() results for an underlying iterator. 15 | // This can help avoid virtual function calls and also gives better 16 | // cache locality. 17 | class IteratorWrapper { 18 | public: 19 | IteratorWrapper(): iter_(NULL), valid_(false) { } 20 | explicit IteratorWrapper(Iterator* iter): iter_(NULL) { 21 | Set(iter); 22 | } 23 | ~IteratorWrapper() { delete iter_; } 24 | Iterator* iter() const { return iter_; } 25 | 26 | // Takes ownership of "iter" and will delete it when destroyed, or 27 | // when Set() is invoked again. 28 | void Set(Iterator* iter) { 29 | delete iter_; 30 | iter_ = iter; 31 | if (iter_ == NULL) { 32 | valid_ = false; 33 | } else { 34 | Update(); 35 | } 36 | } 37 | 38 | 39 | // Iterator interface methods 40 | bool Valid() const { return valid_; } 41 | Slice key() const { assert(Valid()); return key_; } 42 | Slice value() const { assert(Valid()); return iter_->value(); } 43 | // Methods below require iter() != NULL 44 | Status status() const { assert(iter_); return iter_->status(); } 45 | void Next() { assert(iter_); iter_->Next(); Update(); } 46 | void Prev() { assert(iter_); iter_->Prev(); Update(); } 47 | void Seek(const Slice& k) { assert(iter_); iter_->Seek(k); Update(); } 48 | void SeekToFirst() { assert(iter_); iter_->SeekToFirst(); Update(); } 49 | void SeekToLast() { assert(iter_); iter_->SeekToLast(); Update(); } 50 | 51 | private: 52 | void Update() { 53 | valid_ = iter_->Valid(); 54 | if (valid_) { 55 | key_ = iter_->key(); 56 | } 57 | } 58 | 59 | Iterator* iter_; 60 | bool valid_; 61 | Slice key_; 62 | }; 63 | 64 | } // namespace leveldb 65 | 66 | #endif // STORAGE_LEVELDB_TABLE_ITERATOR_WRAPPER_H_ 67 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/util/env_posix_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 | #include "util/env_posix_test_helper.h" 10 | 11 | namespace leveldb { 12 | 13 | static const int kDelayMicros = 100000; 14 | static const int kReadOnlyFileLimit = 4; 15 | static const int kMMapLimit = 4; 16 | 17 | class EnvPosixTest { 18 | public: 19 | Env* env_; 20 | EnvPosixTest() : env_(Env::Default()) { } 21 | 22 | static void SetFileLimits(int read_only_file_limit, int mmap_limit) { 23 | EnvPosixTestHelper::SetReadOnlyFDLimit(read_only_file_limit); 24 | EnvPosixTestHelper::SetReadOnlyMMapLimit(mmap_limit); 25 | } 26 | }; 27 | 28 | TEST(EnvPosixTest, TestOpenOnRead) { 29 | // Write some test data to a single file that will be opened |n| times. 30 | std::string test_dir; 31 | ASSERT_OK(env_->GetTestDirectory(&test_dir)); 32 | std::string test_file = test_dir + "/open_on_read.txt"; 33 | 34 | FILE* f = fopen(test_file.c_str(), "w"); 35 | ASSERT_TRUE(f != NULL); 36 | const char kFileData[] = "abcdefghijklmnopqrstuvwxyz"; 37 | fputs(kFileData, f); 38 | fclose(f); 39 | 40 | // Open test file some number above the sum of the two limits to force 41 | // open-on-read behavior of POSIX Env leveldb::RandomAccessFile. 42 | const int kNumFiles = kReadOnlyFileLimit + kMMapLimit + 5; 43 | leveldb::RandomAccessFile* files[kNumFiles] = {0}; 44 | for (int i = 0; i < kNumFiles; i++) { 45 | ASSERT_OK(env_->NewRandomAccessFile(test_file, &files[i])); 46 | } 47 | char scratch; 48 | Slice read_result; 49 | for (int i = 0; i < kNumFiles; i++) { 50 | ASSERT_OK(files[i]->Read(i, 1, &read_result, &scratch)); 51 | ASSERT_EQ(kFileData[i], read_result[0]); 52 | } 53 | for (int i = 0; i < kNumFiles; i++) { 54 | delete files[i]; 55 | } 56 | ASSERT_OK(env_->DeleteFile(test_file)); 57 | } 58 | 59 | } // namespace leveldb 60 | 61 | int main(int argc, char** argv) { 62 | // All tests currently run with the same read-only file limits. 63 | leveldb::EnvPosixTest::SetFileLimits(leveldb::kReadOnlyFileLimit, 64 | leveldb::kMMapLimit); 65 | return leveldb::test::RunAllTests(); 66 | } 67 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | on: 3 | push: 4 | tags: ['*'] 5 | jobs: 6 | build: 7 | permissions: 8 | contents: read 9 | strategy: 10 | matrix: 11 | include: 12 | - os: ubuntu-latest 13 | arch: x64 14 | build-group: linux-x64 15 | - os: ubuntu-latest 16 | arch: x64 17 | build-group: linux-arm 18 | - os: ubuntu-latest 19 | arch: x64 20 | build-group: android-arm 21 | # At the time of writing macos-latest is mac 10; we need 11 to build a universal binary. 22 | - os: macos-11 23 | arch: x64 24 | build-group: darwin-x64+arm64 25 | - os: windows-latest 26 | arch: x86 27 | build-group: win32-x86 28 | - os: windows-latest 29 | arch: x64 30 | build-group: win32-x64 31 | runs-on: ${{ matrix.os }} 32 | name: Build ${{ matrix.build-group }} 33 | env: 34 | BUILD_GROUP: ${{ matrix.build-group }} 35 | steps: 36 | - name: Checkout 37 | uses: actions/checkout@v3 38 | with: 39 | submodules: recursive 40 | - name: Set up node 41 | uses: actions/setup-node@v3 42 | with: 43 | node-version: 14 44 | architecture: ${{ matrix.arch }} 45 | - name: Install 46 | run: npm install --ignore-scripts 47 | - name: Prebuild 48 | run: npm run prebuild-$BUILD_GROUP 49 | shell: bash 50 | - name: Prepare artifact 51 | run: tar -zcvf $BUILD_GROUP.tar.gz -C prebuilds . 52 | shell: bash 53 | - name: Upload artifact 54 | uses: actions/upload-artifact@v3 55 | with: 56 | name: ${{ env.BUILD_GROUP }} 57 | path: ${{ env.BUILD_GROUP }}.tar.gz 58 | retention-days: 1 59 | release: 60 | needs: build 61 | permissions: 62 | contents: write 63 | runs-on: ubuntu-latest 64 | name: Release 65 | steps: 66 | - name: Checkout 67 | uses: actions/checkout@v3 68 | - name: Download artifacts 69 | uses: actions/download-artifact@v3 70 | with: 71 | path: artifacts 72 | - name: Create GitHub release 73 | uses: docker://antonyurchenko/git-release:v4 74 | env: 75 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 76 | with: 77 | args: artifacts/*/*.tar.gz 78 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 | // Avoid bad seeds. 21 | if (seed_ == 0 || seed_ == 2147483647L) { 22 | seed_ = 1; 23 | } 24 | } 25 | uint32_t Next() { 26 | static const uint32_t M = 2147483647L; // 2^31-1 27 | static const uint64_t A = 16807; // bits 14, 8, 7, 5, 2, 1, 0 28 | // We are computing 29 | // seed_ = (seed_ * A) % M, where M = 2^31-1 30 | // 31 | // seed_ must not be zero or M, or else all subsequent computed values 32 | // will be zero or M respectively. For all other values, seed_ will end 33 | // up cycling through every number in [1,M-1] 34 | uint64_t product = seed_ * A; 35 | 36 | // Compute (product % M) using the fact that ((x << 31) % M) == x. 37 | seed_ = static_cast((product >> 31) + (product & M)); 38 | // The first reduction may overflow by 1 bit, so we may need to 39 | // repeat. mod == M is not possible; using > allows the faster 40 | // sign-bit-based test. 41 | if (seed_ > M) { 42 | seed_ -= M; 43 | } 44 | return seed_; 45 | } 46 | // Returns a uniformly distributed value in the range [0..n-1] 47 | // REQUIRES: n > 0 48 | uint32_t Uniform(int n) { return Next() % n; } 49 | 50 | // Randomly returns true ~"1/n" of the time, and false otherwise. 51 | // REQUIRES: n > 0 52 | bool OneIn(int n) { return (Next() % n) == 0; } 53 | 54 | // Skewed: pick "base" uniformly from range [0,max_log] and then 55 | // return "base" random bits. The effect is to pick a number in the 56 | // range [0,2^max_log-1] with exponential bias towards smaller numbers. 57 | uint32_t Skewed(int max_log) { 58 | return Uniform(1 << Uniform(max_log + 1)); 59 | } 60 | }; 61 | 62 | } // namespace leveldb 63 | 64 | #endif // STORAGE_LEVELDB_UTIL_RANDOM_H_ 65 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/table/filter_block.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 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 filter block is stored near the end of a Table file. It contains 6 | // filters (e.g., bloom filters) for all data blocks in the table combined 7 | // into a single filter block. 8 | 9 | #ifndef STORAGE_LEVELDB_TABLE_FILTER_BLOCK_H_ 10 | #define STORAGE_LEVELDB_TABLE_FILTER_BLOCK_H_ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include "leveldb/slice.h" 17 | #include "util/hash.h" 18 | 19 | namespace leveldb { 20 | 21 | class FilterPolicy; 22 | 23 | // A FilterBlockBuilder is used to construct all of the filters for a 24 | // particular Table. It generates a single string which is stored as 25 | // a special block in the Table. 26 | // 27 | // The sequence of calls to FilterBlockBuilder must match the regexp: 28 | // (StartBlock AddKey*)* Finish 29 | class FilterBlockBuilder { 30 | public: 31 | explicit FilterBlockBuilder(const FilterPolicy*); 32 | 33 | void StartBlock(uint64_t block_offset); 34 | void AddKey(const Slice& key); 35 | Slice Finish(); 36 | 37 | private: 38 | void GenerateFilter(); 39 | 40 | const FilterPolicy* policy_; 41 | std::string keys_; // Flattened key contents 42 | std::vector start_; // Starting index in keys_ of each key 43 | std::string result_; // Filter data computed so far 44 | std::vector tmp_keys_; // policy_->CreateFilter() argument 45 | std::vector filter_offsets_; 46 | 47 | // No copying allowed 48 | FilterBlockBuilder(const FilterBlockBuilder&); 49 | void operator=(const FilterBlockBuilder&); 50 | }; 51 | 52 | class FilterBlockReader { 53 | public: 54 | // REQUIRES: "contents" and *policy must stay live while *this is live. 55 | FilterBlockReader(const FilterPolicy* policy, const Slice& contents); 56 | bool KeyMayMatch(uint64_t block_offset, const Slice& key); 57 | 58 | private: 59 | const FilterPolicy* policy_; 60 | const char* data_; // Pointer to filter data (at block-start) 61 | const char* offset_; // Pointer to beginning of offset array (at block-end) 62 | size_t num_; // Number of entries in offset array 63 | size_t base_lg_; // Encoding parameter (see kFilterBaseLg in .cc file) 64 | }; 65 | 66 | } 67 | 68 | #endif // STORAGE_LEVELDB_TABLE_FILTER_BLOCK_H_ 69 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 7 | #include "leveldb/comparator.h" 8 | #include "leveldb/slice.h" 9 | #include "port/port.h" 10 | #include "util/logging.h" 11 | 12 | namespace leveldb { 13 | 14 | Comparator::~Comparator() { } 15 | 16 | namespace { 17 | class BytewiseComparatorImpl : public Comparator { 18 | public: 19 | BytewiseComparatorImpl() { } 20 | 21 | virtual const char* Name() const { 22 | return "leveldb.BytewiseComparator"; 23 | } 24 | 25 | virtual int Compare(const Slice& a, const Slice& b) const { 26 | return a.compare(b); 27 | } 28 | 29 | virtual void FindShortestSeparator( 30 | std::string* start, 31 | const Slice& limit) const { 32 | // Find length of common prefix 33 | size_t min_length = std::min(start->size(), limit.size()); 34 | size_t diff_index = 0; 35 | while ((diff_index < min_length) && 36 | ((*start)[diff_index] == limit[diff_index])) { 37 | diff_index++; 38 | } 39 | 40 | if (diff_index >= min_length) { 41 | // Do not shorten if one string is a prefix of the other 42 | } else { 43 | uint8_t diff_byte = static_cast((*start)[diff_index]); 44 | if (diff_byte < static_cast(0xff) && 45 | diff_byte + 1 < static_cast(limit[diff_index])) { 46 | (*start)[diff_index]++; 47 | start->resize(diff_index + 1); 48 | assert(Compare(*start, limit) < 0); 49 | } 50 | } 51 | } 52 | 53 | virtual void FindShortSuccessor(std::string* key) const { 54 | // Find first character that can be incremented 55 | size_t n = key->size(); 56 | for (size_t i = 0; i < n; i++) { 57 | const uint8_t byte = (*key)[i]; 58 | if (byte != static_cast(0xff)) { 59 | (*key)[i] = byte + 1; 60 | key->resize(i+1); 61 | return; 62 | } 63 | } 64 | // *key is a run of 0xffs. Leave it alone. 65 | } 66 | }; 67 | } // namespace 68 | 69 | static port::OnceType once = LEVELDB_ONCE_INIT; 70 | static const Comparator* bytewise; 71 | 72 | static void InitModule() { 73 | bytewise = new BytewiseComparatorImpl; 74 | } 75 | 76 | const Comparator* BytewiseComparator() { 77 | port::InitOnce(&once, InitModule); 78 | return bytewise; 79 | } 80 | 81 | } // namespace leveldb 82 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 | Status s; 24 | meta->file_size = 0; 25 | iter->SeekToFirst(); 26 | 27 | std::string fname = TableFileName(dbname, meta->number); 28 | if (iter->Valid()) { 29 | WritableFile* file; 30 | s = env->NewWritableFile(fname, &file); 31 | if (!s.ok()) { 32 | return s; 33 | } 34 | 35 | TableBuilder* builder = new TableBuilder(options, file); 36 | meta->smallest.DecodeFrom(iter->key()); 37 | for (; iter->Valid(); iter->Next()) { 38 | Slice key = iter->key(); 39 | meta->largest.DecodeFrom(key); 40 | builder->Add(key, iter->value()); 41 | } 42 | 43 | // Finish and check for builder errors 44 | if (s.ok()) { 45 | s = builder->Finish(); 46 | if (s.ok()) { 47 | meta->file_size = builder->FileSize(); 48 | assert(meta->file_size > 0); 49 | } 50 | } else { 51 | builder->Abandon(); 52 | } 53 | delete builder; 54 | 55 | // Finish and check for file errors 56 | if (s.ok()) { 57 | s = file->Sync(); 58 | } 59 | if (s.ok()) { 60 | s = file->Close(); 61 | } 62 | delete file; 63 | file = NULL; 64 | 65 | if (s.ok()) { 66 | // Verify that the table is usable 67 | Iterator* it = table_cache->NewIterator(ReadOptions(), 68 | meta->number, 69 | meta->file_size); 70 | s = it->status(); 71 | delete it; 72 | } 73 | } 74 | 75 | // Check for input iterator errors 76 | if (!iter->status().ok()) { 77 | s = iter->status(); 78 | } 79 | 80 | if (s.ok() && meta->file_size > 0) { 81 | // Keep it 82 | } else { 83 | env->DeleteFile(fname); 84 | } 85 | return s; 86 | } 87 | 88 | } // namespace leveldb 89 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "leveldown", 3 | "version": "6.1.1", 4 | "description": "A low-level Node.js LevelDB binding", 5 | "license": "MIT", 6 | "main": "leveldown.js", 7 | "scripts": { 8 | "install": "node-gyp-build", 9 | "test": "standard && (nyc -s tape test/*-test.js | faucet) && nyc report", 10 | "test-gc": "node --expose-gc test/gc.js", 11 | "test-electron": "electron test/electron.js", 12 | "test-prebuild": "cross-env PREBUILDS_ONLY=1 npm t", 13 | "coverage": "nyc report -r lcovonly", 14 | "rebuild": "npm run install --build-from-source", 15 | "prebuild": "prebuildify -t 8.14.0 --napi --strip", 16 | "download-prebuilds": "prebuildify-ci download", 17 | "hallmark": "hallmark --fix", 18 | "dependency-check": "dependency-check --no-dev -i napi-macros . test/*.js", 19 | "prepublishOnly": "npm run dependency-check", 20 | "prebuild-linux-arm": "prebuildify-cross -i linux-armv6 -i linux-armv7 -i linux-arm64 -t 8.14.0 --napi --strip", 21 | "prebuild-android-arm": "prebuildify-cross -i android-armv7 -i android-arm64 -t 8.14.0 --napi --strip", 22 | "prebuild-linux-x64": "prebuildify-cross -i centos7-devtoolset7 -i alpine -t 8.14.0 --napi --strip", 23 | "prebuild-darwin-x64+arm64": "prebuildify -t 8.14.0 --napi --strip --arch x64+arm64", 24 | "prebuild-win32-x86": "prebuildify -t 8.14.0 --napi --strip", 25 | "prebuild-win32-x64": "prebuildify -t 8.14.0 --napi --strip" 26 | }, 27 | "dependencies": { 28 | "abstract-leveldown": "^7.2.0", 29 | "napi-macros": "~2.0.0", 30 | "node-gyp-build": "^4.3.0" 31 | }, 32 | "devDependencies": { 33 | "async-each": "^1.0.3", 34 | "cross-env": "^7.0.3", 35 | "delayed": "^2.0.0", 36 | "dependency-check": "^4.1.0", 37 | "du": "^1.0.0", 38 | "electron": "^19.0.1", 39 | "faucet": "^0.0.1", 40 | "glob": "^7.1.3", 41 | "hallmark": "^4.0.0", 42 | "level-concat-iterator": "^3.0.0", 43 | "mkfiletree": "^2.0.0", 44 | "node-gyp": "^8.4.1", 45 | "nyc": "^15.0.0", 46 | "prebuildify": "^5.0.0", 47 | "prebuildify-ci": "^1.0.4", 48 | "prebuildify-cross": "^5.0.0", 49 | "readfiletree": "^1.0.0", 50 | "rimraf": "^3.0.0", 51 | "standard": "^16.0.3", 52 | "tape": "^5.0.1", 53 | "tempy": "^1.0.1" 54 | }, 55 | "gypfile": true, 56 | "repository": { 57 | "type": "git", 58 | "url": "https://github.com/Level/leveldown.git" 59 | }, 60 | "homepage": "https://github.com/Level/leveldown", 61 | "keywords": [ 62 | "leveldb", 63 | "level" 64 | ], 65 | "engines": { 66 | "node": ">=10.12.0" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /test/iterator-recursion-test.js: -------------------------------------------------------------------------------- 1 | const test = require('tape') 2 | const testCommon = require('./common') 3 | const fork = require('child_process').fork 4 | const path = require('path') 5 | 6 | let db 7 | 8 | const sourceData = (function () { 9 | const d = [] 10 | let i = 0 11 | let k 12 | for (; i < 100000; i++) { 13 | k = (i < 10 ? '0' : '') + i 14 | d.push({ 15 | type: 'put', 16 | key: k, 17 | value: Math.random() 18 | }) 19 | } 20 | return d 21 | }()) 22 | 23 | test('setUp common', testCommon.setUp) 24 | 25 | // TODO: fix this test. It asserted that we didn't segfault if user code had an 26 | // infinite loop leading to stack exhaustion, which caused a node::FatalException() 27 | // call in our Iterator to segfault. This was fixed in 2014 (commit 85e6a38). 28 | // 29 | // Today (2020), we see occasional failures in CI again. We no longer call 30 | // node::FatalException() so there's a new reason. 31 | test.skip('try to create an iterator with a blown stack', function (t) { 32 | for (let i = 0; i < 100; i++) { 33 | t.test(`try to create an iterator with a blown stack (${i})`, function (t) { 34 | t.plan(3) 35 | 36 | // Reducing the stack size down from the default 984 for the child node 37 | // process makes it easier to trigger the bug condition. But making it too low 38 | // causes the child process to die for other reasons. 39 | const opts = { execArgv: ['--stack-size=128'] } 40 | const child = fork(path.join(__dirname, 'stack-blower.js'), ['run'], opts) 41 | 42 | child.on('message', function (m) { 43 | t.ok(true, m) 44 | child.disconnect() 45 | }) 46 | 47 | child.on('exit', function (code, sig) { 48 | t.is(code, 0, 'child exited normally') 49 | t.is(sig, null, 'not terminated due to signal') 50 | }) 51 | }) 52 | } 53 | 54 | t.end() 55 | }) 56 | 57 | test('setUp db', function (t) { 58 | db = testCommon.factory() 59 | db.open(function (err) { 60 | t.error(err) 61 | db.batch(sourceData, t.end.bind(t)) 62 | }) 63 | }) 64 | 65 | test('iterate over a large iterator with a large watermark', function (t) { 66 | const iterator = db.iterator({ 67 | highWaterMark: 10000000 68 | }) 69 | const read = function () { 70 | iterator.next(function (err, key, value) { 71 | if (err) throw err 72 | 73 | if (key === undefined && value === undefined) { 74 | t.end() 75 | } else { 76 | read() 77 | } 78 | }) 79 | } 80 | 81 | read() 82 | }) 83 | 84 | test('tearDown', function (t) { 85 | db.close(testCommon.tearDown.bind(null, t)) 86 | }) 87 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 | } // namespace leveldb 62 | 63 | #endif // STORAGE_LEVELDB_INCLUDE_COMPARATOR_H_ 64 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 | Status Env::NewAppendableFile(const std::string& fname, WritableFile** result) { 13 | return Status::NotSupported("NewAppendableFile", fname); 14 | } 15 | 16 | SequentialFile::~SequentialFile() { 17 | } 18 | 19 | RandomAccessFile::~RandomAccessFile() { 20 | } 21 | 22 | WritableFile::~WritableFile() { 23 | } 24 | 25 | Logger::~Logger() { 26 | } 27 | 28 | FileLock::~FileLock() { 29 | } 30 | 31 | void Log(Logger* info_log, const char* format, ...) { 32 | if (info_log != NULL) { 33 | va_list ap; 34 | va_start(ap, format); 35 | info_log->Logv(format, ap); 36 | va_end(ap); 37 | } 38 | } 39 | 40 | static Status DoWriteStringToFile(Env* env, const Slice& data, 41 | const std::string& fname, 42 | bool should_sync) { 43 | WritableFile* file; 44 | Status s = env->NewWritableFile(fname, &file); 45 | if (!s.ok()) { 46 | return s; 47 | } 48 | s = file->Append(data); 49 | if (s.ok() && should_sync) { 50 | s = file->Sync(); 51 | } 52 | if (s.ok()) { 53 | s = file->Close(); 54 | } 55 | delete file; // Will auto-close if we did not close above 56 | if (!s.ok()) { 57 | env->DeleteFile(fname); 58 | } 59 | return s; 60 | } 61 | 62 | Status WriteStringToFile(Env* env, const Slice& data, 63 | const std::string& fname) { 64 | return DoWriteStringToFile(env, data, fname, false); 65 | } 66 | 67 | Status WriteStringToFileSync(Env* env, const Slice& data, 68 | const std::string& fname) { 69 | return DoWriteStringToFile(env, data, fname, true); 70 | } 71 | 72 | Status ReadFileToString(Env* env, const std::string& fname, std::string* data) { 73 | data->clear(); 74 | SequentialFile* file; 75 | Status s = env->NewSequentialFile(fname, &file); 76 | if (!s.ok()) { 77 | return s; 78 | } 79 | static const int kBufferSize = 8192; 80 | char* space = new char[kBufferSize]; 81 | while (true) { 82 | Slice fragment; 83 | s = file->Read(kBufferSize, &fragment, space); 84 | if (!s.ok()) { 85 | break; 86 | } 87 | data->append(fragment.data(), fragment.size()); 88 | if (fragment.empty()) { 89 | break; 90 | } 91 | } 92 | delete[] space; 93 | delete file; 94 | return s; 95 | } 96 | 97 | EnvWrapper::~EnvWrapper() { 98 | } 99 | 100 | } // namespace leveldb 101 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/issues/issue178_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 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 | // Test for issue 178: a manual compaction causes deleted data to reappear. 6 | #include 7 | #include 8 | #include 9 | 10 | #include "leveldb/db.h" 11 | #include "leveldb/write_batch.h" 12 | #include "util/testharness.h" 13 | 14 | namespace { 15 | 16 | const int kNumKeys = 1100000; 17 | 18 | std::string Key1(int i) { 19 | char buf[100]; 20 | snprintf(buf, sizeof(buf), "my_key_%d", i); 21 | return buf; 22 | } 23 | 24 | std::string Key2(int i) { 25 | return Key1(i) + "_xxx"; 26 | } 27 | 28 | class Issue178 { }; 29 | 30 | TEST(Issue178, Test) { 31 | // Get rid of any state from an old run. 32 | std::string dbpath = leveldb::test::TmpDir() + "/leveldb_cbug_test"; 33 | DestroyDB(dbpath, leveldb::Options()); 34 | 35 | // Open database. Disable compression since it affects the creation 36 | // of layers and the code below is trying to test against a very 37 | // specific scenario. 38 | leveldb::DB* db; 39 | leveldb::Options db_options; 40 | db_options.create_if_missing = true; 41 | db_options.compression = leveldb::kNoCompression; 42 | ASSERT_OK(leveldb::DB::Open(db_options, dbpath, &db)); 43 | 44 | // create first key range 45 | leveldb::WriteBatch batch; 46 | for (size_t i = 0; i < kNumKeys; i++) { 47 | batch.Put(Key1(i), "value for range 1 key"); 48 | } 49 | ASSERT_OK(db->Write(leveldb::WriteOptions(), &batch)); 50 | 51 | // create second key range 52 | batch.Clear(); 53 | for (size_t i = 0; i < kNumKeys; i++) { 54 | batch.Put(Key2(i), "value for range 2 key"); 55 | } 56 | ASSERT_OK(db->Write(leveldb::WriteOptions(), &batch)); 57 | 58 | // delete second key range 59 | batch.Clear(); 60 | for (size_t i = 0; i < kNumKeys; i++) { 61 | batch.Delete(Key2(i)); 62 | } 63 | ASSERT_OK(db->Write(leveldb::WriteOptions(), &batch)); 64 | 65 | // compact database 66 | std::string start_key = Key1(0); 67 | std::string end_key = Key1(kNumKeys - 1); 68 | leveldb::Slice least(start_key.data(), start_key.size()); 69 | leveldb::Slice greatest(end_key.data(), end_key.size()); 70 | 71 | // commenting out the line below causes the example to work correctly 72 | db->CompactRange(&least, &greatest); 73 | 74 | // count the keys 75 | leveldb::Iterator* iter = db->NewIterator(leveldb::ReadOptions()); 76 | size_t num_keys = 0; 77 | for (iter->SeekToFirst(); iter->Valid(); iter->Next()) { 78 | num_keys++; 79 | } 80 | delete iter; 81 | ASSERT_EQ(kNumKeys, num_keys) << "Bad number of keys"; 82 | 83 | // close database 84 | delete db; 85 | DestroyDB(dbpath, leveldb::Options()); 86 | } 87 | 88 | } // anonymous namespace 89 | 90 | int main(int argc, char** argv) { 91 | return leveldb::test::RunAllTests(); 92 | } 93 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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. It is safe to call when MemTable is being modified. 40 | size_t ApproximateMemoryUsage(); 41 | 42 | // Return an iterator that yields the contents of the memtable. 43 | // 44 | // The caller must ensure that the underlying MemTable remains live 45 | // while the returned iterator is live. The keys returned by this 46 | // iterator are internal keys encoded by AppendInternalKey in the 47 | // db/format.{h,cc} module. 48 | Iterator* NewIterator(); 49 | 50 | // Add an entry into memtable that maps key to value at the 51 | // specified sequence number and with the specified type. 52 | // Typically value will be empty if type==kTypeDeletion. 53 | void Add(SequenceNumber seq, ValueType type, 54 | const Slice& key, 55 | const Slice& value); 56 | 57 | // If memtable contains a value for key, store it in *value and return true. 58 | // If memtable contains a deletion for key, store a NotFound() error 59 | // in *status and return true. 60 | // Else, return false. 61 | bool Get(const LookupKey& key, std::string* value, Status* s); 62 | 63 | private: 64 | ~MemTable(); // Private since only Unref() should be used to delete it 65 | 66 | struct KeyComparator { 67 | const InternalKeyComparator comparator; 68 | explicit KeyComparator(const InternalKeyComparator& c) : comparator(c) { } 69 | int operator()(const char* a, const char* b) const; 70 | }; 71 | friend class MemTableIterator; 72 | friend class MemTableBackwardIterator; 73 | 74 | typedef SkipList Table; 75 | 76 | KeyComparator comparator_; 77 | int refs_; 78 | Arena arena_; 79 | Table table_; 80 | 81 | // No copying allowed 82 | MemTable(const MemTable&); 83 | void operator=(const MemTable&); 84 | }; 85 | 86 | } // namespace leveldb 87 | 88 | #endif // STORAGE_LEVELDB_DB_MEMTABLE_H_ 89 | -------------------------------------------------------------------------------- /test/compression-test.js: -------------------------------------------------------------------------------- 1 | const each = require('async-each') 2 | const du = require('du') 3 | const delayed = require('delayed') 4 | const testCommon = require('./common') 5 | const leveldown = require('..') 6 | const test = require('tape') 7 | 8 | const compressableData = Buffer.from(Array.apply(null, Array(1024 * 100)).map(function () { 9 | return 'aaaaaaaaaa' 10 | }).join('')) 11 | 12 | const multiples = 10 13 | const dataSize = compressableData.length * multiples 14 | 15 | const verify = function (location, compression, t) { 16 | du(location, function (err, size) { 17 | t.error(err) 18 | if (compression) { 19 | t.ok(size < dataSize, 'on-disk size (' + size + ') is less than data size (' + dataSize + ')') 20 | } else { 21 | t.ok(size >= dataSize, 'on-disk size (' + size + ') is greater than data size (' + dataSize + ')') 22 | } 23 | t.end() 24 | }) 25 | } 26 | 27 | // close, open, close again.. 'compaction' is also performed on open()s 28 | const cycle = function (db, compression, t, callback) { 29 | const location = db.location 30 | db.close(function (err) { 31 | t.error(err) 32 | db = leveldown(location) 33 | db.open({ errorIfExists: false, compression: compression }, function () { 34 | t.error(err) 35 | db.close(function (err) { 36 | t.error(err) 37 | callback() 38 | }) 39 | }) 40 | }) 41 | } 42 | 43 | test('compression', function (t) { 44 | t.plan(4) 45 | t.test('set up', testCommon.setUp) 46 | 47 | t.test('test data is compressed by default (db.put())', function (t) { 48 | const db = testCommon.factory() 49 | db.open(function (err) { 50 | t.error(err) 51 | each( 52 | Array.apply(null, Array(multiples)).map(function (e, i) { 53 | return [i, compressableData] 54 | }), function (args, callback) { 55 | db.put.apply(db, args.concat([callback])) 56 | }, cycle.bind(null, db, true, t, delayed.delayed(verify.bind(null, db.location, true, t), 0.01)) 57 | ) 58 | }) 59 | }) 60 | 61 | t.test('test data is not compressed with compression=false on open() (db.put())', function (t) { 62 | const db = testCommon.factory() 63 | db.open({ compression: false }, function (err) { 64 | t.error(err) 65 | each( 66 | Array.apply(null, Array(multiples)).map(function (e, i) { 67 | return [i, compressableData] 68 | }), function (args, callback) { 69 | db.put.apply(db, args.concat([callback])) 70 | }, cycle.bind(null, db, false, t, delayed.delayed(verify.bind(null, db.location, false, t), 0.01)) 71 | ) 72 | }) 73 | }) 74 | 75 | t.test('test data is compressed by default (db.batch())', function (t) { 76 | const db = testCommon.factory() 77 | db.open(function (err) { 78 | t.error(err) 79 | db.batch( 80 | Array.apply(null, Array(multiples)).map(function (e, i) { 81 | return { type: 'put', key: i, value: compressableData } 82 | }), cycle.bind(null, db, true, t, delayed.delayed(verify.bind(null, db.location, true, t), 0.01)) 83 | ) 84 | }) 85 | }) 86 | }) 87 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 | static const int kReadOnlyFileLimit = 4; 14 | static const int kMMapLimit = 4; 15 | 16 | class EnvTest { 17 | private: 18 | port::Mutex mu_; 19 | std::string events_; 20 | 21 | public: 22 | Env* env_; 23 | EnvTest() : env_(Env::Default()) { } 24 | }; 25 | 26 | static void SetBool(void* ptr) { 27 | reinterpret_cast(ptr)->NoBarrier_Store(ptr); 28 | } 29 | 30 | TEST(EnvTest, RunImmediately) { 31 | port::AtomicPointer called (NULL); 32 | env_->Schedule(&SetBool, &called); 33 | env_->SleepForMicroseconds(kDelayMicros); 34 | ASSERT_TRUE(called.NoBarrier_Load() != NULL); 35 | } 36 | 37 | TEST(EnvTest, RunMany) { 38 | port::AtomicPointer last_id (NULL); 39 | 40 | struct CB { 41 | port::AtomicPointer* last_id_ptr; // Pointer to shared slot 42 | uintptr_t id; // Order# for the execution of this callback 43 | 44 | CB(port::AtomicPointer* p, int i) : last_id_ptr(p), id(i) { } 45 | 46 | static void Run(void* v) { 47 | CB* cb = reinterpret_cast(v); 48 | void* cur = cb->last_id_ptr->NoBarrier_Load(); 49 | ASSERT_EQ(cb->id-1, reinterpret_cast(cur)); 50 | cb->last_id_ptr->Release_Store(reinterpret_cast(cb->id)); 51 | } 52 | }; 53 | 54 | // Schedule in different order than start time 55 | CB cb1(&last_id, 1); 56 | CB cb2(&last_id, 2); 57 | CB cb3(&last_id, 3); 58 | CB cb4(&last_id, 4); 59 | env_->Schedule(&CB::Run, &cb1); 60 | env_->Schedule(&CB::Run, &cb2); 61 | env_->Schedule(&CB::Run, &cb3); 62 | env_->Schedule(&CB::Run, &cb4); 63 | 64 | env_->SleepForMicroseconds(kDelayMicros); 65 | void* cur = last_id.Acquire_Load(); 66 | ASSERT_EQ(4, reinterpret_cast(cur)); 67 | } 68 | 69 | struct State { 70 | port::Mutex mu; 71 | int val; 72 | int num_running; 73 | }; 74 | 75 | static void ThreadBody(void* arg) { 76 | State* s = reinterpret_cast(arg); 77 | s->mu.Lock(); 78 | s->val += 1; 79 | s->num_running -= 1; 80 | s->mu.Unlock(); 81 | } 82 | 83 | TEST(EnvTest, StartThread) { 84 | State state; 85 | state.val = 0; 86 | state.num_running = 3; 87 | for (int i = 0; i < 3; i++) { 88 | env_->StartThread(&ThreadBody, &state); 89 | } 90 | while (true) { 91 | state.mu.Lock(); 92 | int num = state.num_running; 93 | state.mu.Unlock(); 94 | if (num == 0) { 95 | break; 96 | } 97 | env_->SleepForMicroseconds(kDelayMicros); 98 | } 99 | ASSERT_EQ(state.val, 3); 100 | } 101 | 102 | } // namespace leveldb 103 | 104 | int main(int argc, char** argv) { 105 | return leveldb::test::RunAllTests(); 106 | } 107 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/util/posix_logger.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 | // Logger implementation that can be shared by all environments 6 | // where enough posix functionality is available. 7 | 8 | #ifndef STORAGE_LEVELDB_UTIL_POSIX_LOGGER_H_ 9 | #define STORAGE_LEVELDB_UTIL_POSIX_LOGGER_H_ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include "leveldb/env.h" 16 | 17 | namespace leveldb { 18 | 19 | class PosixLogger : public Logger { 20 | private: 21 | FILE* file_; 22 | uint64_t (*gettid_)(); // Return the thread id for the current thread 23 | public: 24 | PosixLogger(FILE* f, uint64_t (*gettid)()) : file_(f), gettid_(gettid) { } 25 | virtual ~PosixLogger() { 26 | fclose(file_); 27 | } 28 | virtual void Logv(const char* format, va_list ap) { 29 | const uint64_t thread_id = (*gettid_)(); 30 | 31 | // We try twice: the first time with a fixed-size stack allocated buffer, 32 | // and the second time with a much larger dynamically allocated buffer. 33 | char buffer[500]; 34 | for (int iter = 0; iter < 2; iter++) { 35 | char* base; 36 | int bufsize; 37 | if (iter == 0) { 38 | bufsize = sizeof(buffer); 39 | base = buffer; 40 | } else { 41 | bufsize = 30000; 42 | base = new char[bufsize]; 43 | } 44 | char* p = base; 45 | char* limit = base + bufsize; 46 | 47 | struct timeval now_tv; 48 | gettimeofday(&now_tv, NULL); 49 | const time_t seconds = now_tv.tv_sec; 50 | struct tm t; 51 | localtime_r(&seconds, &t); 52 | p += snprintf(p, limit - p, 53 | "%04d/%02d/%02d-%02d:%02d:%02d.%06d %llx ", 54 | t.tm_year + 1900, 55 | t.tm_mon + 1, 56 | t.tm_mday, 57 | t.tm_hour, 58 | t.tm_min, 59 | t.tm_sec, 60 | static_cast(now_tv.tv_usec), 61 | static_cast(thread_id)); 62 | 63 | // Print the message 64 | if (p < limit) { 65 | va_list backup_ap; 66 | va_copy(backup_ap, ap); 67 | p += vsnprintf(p, limit - p, format, backup_ap); 68 | va_end(backup_ap); 69 | } 70 | 71 | // Truncate to available space if necessary 72 | if (p >= limit) { 73 | if (iter == 0) { 74 | continue; // Try again with larger buffer 75 | } else { 76 | p = limit - 1; 77 | } 78 | } 79 | 80 | // Add newline if necessary 81 | if (p == base || p[-1] != '\n') { 82 | *p++ = '\n'; 83 | } 84 | 85 | assert(p <= limit); 86 | fwrite(base, 1, p - base, file_); 87 | fflush(file_); 88 | if (base != buffer) { 89 | delete[] base; 90 | } 91 | break; 92 | } 93 | } 94 | }; 95 | 96 | } // namespace leveldb 97 | 98 | #endif // STORAGE_LEVELDB_UTIL_POSIX_LOGGER_H_ 99 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/include/leveldb/filter_policy.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 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 database can be configured with a custom FilterPolicy object. 6 | // This object is responsible for creating a small filter from a set 7 | // of keys. These filters are stored in leveldb and are consulted 8 | // automatically by leveldb to decide whether or not to read some 9 | // information from disk. In many cases, a filter can cut down the 10 | // number of disk seeks form a handful to a single disk seek per 11 | // DB::Get() call. 12 | // 13 | // Most people will want to use the builtin bloom filter support (see 14 | // NewBloomFilterPolicy() below). 15 | 16 | #ifndef STORAGE_LEVELDB_INCLUDE_FILTER_POLICY_H_ 17 | #define STORAGE_LEVELDB_INCLUDE_FILTER_POLICY_H_ 18 | 19 | #include 20 | 21 | namespace leveldb { 22 | 23 | class Slice; 24 | 25 | class FilterPolicy { 26 | public: 27 | virtual ~FilterPolicy(); 28 | 29 | // Return the name of this policy. Note that if the filter encoding 30 | // changes in an incompatible way, the name returned by this method 31 | // must be changed. Otherwise, old incompatible filters may be 32 | // passed to methods of this type. 33 | virtual const char* Name() const = 0; 34 | 35 | // keys[0,n-1] contains a list of keys (potentially with duplicates) 36 | // that are ordered according to the user supplied comparator. 37 | // Append a filter that summarizes keys[0,n-1] to *dst. 38 | // 39 | // Warning: do not change the initial contents of *dst. Instead, 40 | // append the newly constructed filter to *dst. 41 | virtual void CreateFilter(const Slice* keys, int n, std::string* dst) 42 | const = 0; 43 | 44 | // "filter" contains the data appended by a preceding call to 45 | // CreateFilter() on this class. This method must return true if 46 | // the key was in the list of keys passed to CreateFilter(). 47 | // This method may return true or false if the key was not on the 48 | // list, but it should aim to return false with a high probability. 49 | virtual bool KeyMayMatch(const Slice& key, const Slice& filter) const = 0; 50 | }; 51 | 52 | // Return a new filter policy that uses a bloom filter with approximately 53 | // the specified number of bits per key. A good value for bits_per_key 54 | // is 10, which yields a filter with ~ 1% false positive rate. 55 | // 56 | // Callers must delete the result after any database that is using the 57 | // result has been closed. 58 | // 59 | // Note: if you are using a custom comparator that ignores some parts 60 | // of the keys being compared, you must not use NewBloomFilterPolicy() 61 | // and must provide your own FilterPolicy that also ignores the 62 | // corresponding parts of the keys. For example, if the comparator 63 | // ignores trailing spaces, it would be incorrect to use a 64 | // FilterPolicy (like NewBloomFilterPolicy) that does not ignore 65 | // trailing spaces in keys. 66 | extern const FilterPolicy* NewBloomFilterPolicy(int bits_per_key); 67 | 68 | } 69 | 70 | #endif // STORAGE_LEVELDB_INCLUDE_FILTER_POLICY_H_ 71 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/doc/log_format.md: -------------------------------------------------------------------------------- 1 | leveldb Log format 2 | ================== 3 | The log file contents are a sequence of 32KB blocks. The only exception is that 4 | the tail of the file may contain a partial block. 5 | 6 | Each block consists of a sequence of records: 7 | 8 | block := record* trailer? 9 | record := 10 | checksum: uint32 // crc32c of type and data[] ; little-endian 11 | length: uint16 // little-endian 12 | type: uint8 // One of FULL, FIRST, MIDDLE, LAST 13 | data: uint8[length] 14 | 15 | A record never starts within the last six bytes of a block (since it won't fit). 16 | Any leftover bytes here form the trailer, which must consist entirely of zero 17 | bytes and must be skipped by readers. 18 | 19 | Aside: if exactly seven bytes are left in the current block, and a new non-zero 20 | length record is added, the writer must emit a FIRST record (which contains zero 21 | bytes of user data) to fill up the trailing seven bytes of the block and then 22 | emit all of the user data in subsequent blocks. 23 | 24 | More types may be added in the future. Some Readers may skip record types they 25 | do not understand, others may report that some data was skipped. 26 | 27 | FULL == 1 28 | FIRST == 2 29 | MIDDLE == 3 30 | LAST == 4 31 | 32 | The FULL record contains the contents of an entire user record. 33 | 34 | FIRST, MIDDLE, LAST are types used for user records that have been split into 35 | multiple fragments (typically because of block boundaries). FIRST is the type 36 | of the first fragment of a user record, LAST is the type of the last fragment of 37 | a user record, and MIDDLE is the type of all interior fragments of a user 38 | record. 39 | 40 | Example: consider a sequence of user records: 41 | 42 | A: length 1000 43 | B: length 97270 44 | C: length 8000 45 | 46 | **A** will be stored as a FULL record in the first block. 47 | 48 | **B** will be split into three fragments: first fragment occupies the rest of 49 | the first block, second fragment occupies the entirety of the second block, and 50 | the third fragment occupies a prefix of the third block. This will leave six 51 | bytes free in the third block, which will be left empty as the trailer. 52 | 53 | **C** will be stored as a FULL record in the fourth block. 54 | 55 | ---- 56 | 57 | ## Some benefits over the recordio format: 58 | 59 | 1. We do not need any heuristics for resyncing - just go to next block boundary 60 | and scan. If there is a corruption, skip to the next block. As a 61 | side-benefit, we do not get confused when part of the contents of one log 62 | file are embedded as a record inside another log file. 63 | 64 | 2. Splitting at approximate boundaries (e.g., for mapreduce) is simple: find the 65 | next block boundary and skip records until we 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 record type, 72 | so it is a shortcoming of the current implementation, not necessarily the 73 | format. 74 | 75 | 2. No compression. Again, this could be fixed by adding new record types. 76 | -------------------------------------------------------------------------------- /test/segfault-test.js: -------------------------------------------------------------------------------- 1 | const test = require('tape') 2 | const testCommon = require('./common') 3 | const operations = [] 4 | 5 | // The db must wait for pending operations to finish before closing. This to 6 | // prevent segfaults and in the case of compactRange() to prevent hanging. See 7 | // https://github.com/Level/leveldown/issues/157 and 32. 8 | function testPending (name, expectedCount, fn) { 9 | operations.push(fn) 10 | 11 | test(`close() waits for pending ${name}`, function (t) { 12 | const db = testCommon.factory() 13 | let count = 0 14 | 15 | db.open(function (err) { 16 | t.ifError(err, 'no error from open()') 17 | 18 | db.put('key', 'value', function (err) { 19 | t.ifError(err, 'no error from put()') 20 | 21 | fn(db, function (err) { 22 | count++ 23 | t.ifError(err, 'no error from operation') 24 | }) 25 | 26 | db.close(function (err) { 27 | t.ifError(err, 'no error from close()') 28 | t.is(count, expectedCount, 'operation(s) finished before close') 29 | t.end() 30 | }) 31 | }) 32 | }) 33 | }) 34 | } 35 | 36 | testPending('get()', 1, function (db, next) { 37 | db.get('key', next) 38 | }) 39 | 40 | testPending('put()', 1, function (db, next) { 41 | db.put('key2', 'value', next) 42 | }) 43 | 44 | testPending('put() with { sync }', 1, function (db, next) { 45 | // The sync option makes the operation slower and thus more likely to 46 | // cause a segfault (if closing were to happen during the operation). 47 | db.put('key2', 'value', { sync: true }, next) 48 | }) 49 | 50 | testPending('del()', 1, function (db, next) { 51 | db.del('key', next) 52 | }) 53 | 54 | testPending('del() with { sync }', 1, function (db, next) { 55 | db.del('key', { sync: true }, next) 56 | }) 57 | 58 | testPending('batch([])', 1, function (db, next) { 59 | db.batch([{ type: 'del', key: 'key' }], next) 60 | }) 61 | 62 | testPending('batch([]) with { sync }', 1, function (db, next) { 63 | db.batch([{ type: 'del', key: 'key' }], { sync: true }, next) 64 | }) 65 | 66 | testPending('batch()', 1, function (db, next) { 67 | db.batch().del('key').write(next) 68 | }) 69 | 70 | testPending('batch() with { sync }', 1, function (db, next) { 71 | db.batch().del('key').write({ sync: true }, next) 72 | }) 73 | 74 | testPending('approximateSize()', 1, function (db, next) { 75 | db.approximateSize('a', 'z', next) 76 | }) 77 | 78 | testPending('compactRange()', 1, function (db, next) { 79 | db.compactRange('a', 'z', next) 80 | }) 81 | 82 | // Test multiple pending operations, using all of the above. 83 | testPending('operations', operations.length, function (db, next) { 84 | for (const fn of operations.slice(0, -1)) { 85 | fn(db, next) 86 | } 87 | }) 88 | 89 | // See https://github.com/Level/leveldown/issues/134 90 | test('iterator() does not segfault if db is not open', function (t) { 91 | t.plan(2) 92 | 93 | const db = testCommon.factory() 94 | 95 | try { 96 | db.iterator() 97 | } catch (err) { 98 | t.is(err.message, 'cannot call iterator() before open()') 99 | } 100 | 101 | db.close(function (err) { 102 | t.ifError(err, 'no close error') 103 | }) 104 | }) 105 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/util/bloom.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 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/filter_policy.h" 6 | 7 | #include "leveldb/slice.h" 8 | #include "util/hash.h" 9 | 10 | namespace leveldb { 11 | 12 | namespace { 13 | static uint32_t BloomHash(const Slice& key) { 14 | return Hash(key.data(), key.size(), 0xbc9f1d34); 15 | } 16 | 17 | class BloomFilterPolicy : public FilterPolicy { 18 | private: 19 | size_t bits_per_key_; 20 | size_t k_; 21 | 22 | public: 23 | explicit BloomFilterPolicy(int bits_per_key) 24 | : bits_per_key_(bits_per_key) { 25 | // We intentionally round down to reduce probing cost a little bit 26 | k_ = static_cast(bits_per_key * 0.69); // 0.69 =~ ln(2) 27 | if (k_ < 1) k_ = 1; 28 | if (k_ > 30) k_ = 30; 29 | } 30 | 31 | virtual const char* Name() const { 32 | return "leveldb.BuiltinBloomFilter2"; 33 | } 34 | 35 | virtual void CreateFilter(const Slice* keys, int n, std::string* dst) const { 36 | // Compute bloom filter size (in both bits and bytes) 37 | size_t bits = n * bits_per_key_; 38 | 39 | // For small n, we can see a very high false positive rate. Fix it 40 | // by enforcing a minimum bloom filter length. 41 | if (bits < 64) bits = 64; 42 | 43 | size_t bytes = (bits + 7) / 8; 44 | bits = bytes * 8; 45 | 46 | const size_t init_size = dst->size(); 47 | dst->resize(init_size + bytes, 0); 48 | dst->push_back(static_cast(k_)); // Remember # of probes in filter 49 | char* array = &(*dst)[init_size]; 50 | for (int i = 0; i < n; i++) { 51 | // Use double-hashing to generate a sequence of hash values. 52 | // See analysis in [Kirsch,Mitzenmacher 2006]. 53 | uint32_t h = BloomHash(keys[i]); 54 | const uint32_t delta = (h >> 17) | (h << 15); // Rotate right 17 bits 55 | for (size_t j = 0; j < k_; j++) { 56 | const uint32_t bitpos = h % bits; 57 | array[bitpos/8] |= (1 << (bitpos % 8)); 58 | h += delta; 59 | } 60 | } 61 | } 62 | 63 | virtual bool KeyMayMatch(const Slice& key, const Slice& bloom_filter) const { 64 | const size_t len = bloom_filter.size(); 65 | if (len < 2) return false; 66 | 67 | const char* array = bloom_filter.data(); 68 | const size_t bits = (len - 1) * 8; 69 | 70 | // Use the encoded k so that we can read filters generated by 71 | // bloom filters created using different parameters. 72 | const size_t k = array[len-1]; 73 | if (k > 30) { 74 | // Reserved for potentially new encodings for short bloom filters. 75 | // Consider it a match. 76 | return true; 77 | } 78 | 79 | uint32_t h = BloomHash(key); 80 | const uint32_t delta = (h >> 17) | (h << 15); // Rotate right 17 bits 81 | for (size_t j = 0; j < k; j++) { 82 | const uint32_t bitpos = h % bits; 83 | if ((array[bitpos/8] & (1 << (bitpos % 8))) == 0) return false; 84 | h += delta; 85 | } 86 | return true; 87 | } 88 | }; 89 | } 90 | 91 | const FilterPolicy* NewBloomFilterPolicy(int bits_per_key) { 92 | return new BloomFilterPolicy(bits_per_key); 93 | } 94 | 95 | } // namespace leveldb 96 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 | class Footer; 16 | struct Options; 17 | class RandomAccessFile; 18 | struct ReadOptions; 19 | class TableCache; 20 | 21 | // A Table is a sorted map from strings to strings. Tables are 22 | // immutable and persistent. A Table may be safely accessed from 23 | // multiple threads without external synchronization. 24 | class Table { 25 | public: 26 | // Attempt to open the table that is stored in bytes [0..file_size) 27 | // of "file", and read the metadata entries necessary to allow 28 | // retrieving data from the table. 29 | // 30 | // If successful, returns ok and sets "*table" to the newly opened 31 | // table. The client should delete "*table" when no longer needed. 32 | // If there was an error while initializing the table, sets "*table" 33 | // to NULL and returns a non-ok status. Does not take ownership of 34 | // "*source", but the client must ensure that "source" remains live 35 | // for the duration of the returned table's lifetime. 36 | // 37 | // *file must remain live while this Table is in use. 38 | static Status Open(const Options& options, 39 | RandomAccessFile* file, 40 | uint64_t file_size, 41 | Table** table); 42 | 43 | ~Table(); 44 | 45 | // Returns a new iterator over the table contents. 46 | // The result of NewIterator() is initially invalid (caller must 47 | // call one of the Seek methods on the iterator before using it). 48 | Iterator* NewIterator(const ReadOptions&) const; 49 | 50 | // Given a key, return an approximate byte offset in the file where 51 | // the data for that key begins (or would begin if the key were 52 | // present in the file). The returned value is in terms of file 53 | // bytes, and so includes effects like compression of the underlying data. 54 | // E.g., the approximate offset of the last key in the table will 55 | // be close to the file length. 56 | uint64_t ApproximateOffsetOf(const Slice& key) const; 57 | 58 | private: 59 | struct Rep; 60 | Rep* rep_; 61 | 62 | explicit Table(Rep* rep) { rep_ = rep; } 63 | static Iterator* BlockReader(void*, const ReadOptions&, const Slice&); 64 | 65 | // Calls (*handle_result)(arg, ...) with the entry found after a call 66 | // to Seek(key). May not make such a call if filter policy says 67 | // that key is not present. 68 | friend class TableCache; 69 | Status InternalGet( 70 | const ReadOptions&, const Slice& key, 71 | void* arg, 72 | void (*handle_result)(void* arg, const Slice& k, const Slice& v)); 73 | 74 | 75 | void ReadMeta(const Footer& footer); 76 | void ReadFilter(const Slice& filter_handle_value); 77 | 78 | // No copying allowed 79 | Table(const Table&); 80 | void operator=(const Table&); 81 | }; 82 | 83 | } // namespace leveldb 84 | 85 | #endif // STORAGE_LEVELDB_INCLUDE_TABLE_H_ 86 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 legacy file name for an sstable with the specified number 41 | // in the db named by "dbname". The result will be prefixed with 42 | // "dbname". 43 | extern std::string SSTTableFileName(const std::string& dbname, uint64_t number); 44 | 45 | // Return the name of the descriptor file for the db named by 46 | // "dbname" and the specified incarnation number. The result will be 47 | // prefixed with "dbname". 48 | extern std::string DescriptorFileName(const std::string& dbname, 49 | uint64_t number); 50 | 51 | // Return the name of the current file. This file contains the name 52 | // of the current manifest file. The result will be prefixed with 53 | // "dbname". 54 | extern std::string CurrentFileName(const std::string& dbname); 55 | 56 | // Return the name of the lock file for the db named by 57 | // "dbname". The result will be prefixed with "dbname". 58 | extern std::string LockFileName(const std::string& dbname); 59 | 60 | // Return the name of a temporary file owned by the db named "dbname". 61 | // The result will be prefixed with "dbname". 62 | extern std::string TempFileName(const std::string& dbname, uint64_t number); 63 | 64 | // Return the name of the info log file for "dbname". 65 | extern std::string InfoLogFileName(const std::string& dbname); 66 | 67 | // Return the name of the old info log file for "dbname". 68 | extern std::string OldInfoLogFileName(const std::string& dbname); 69 | 70 | // If filename is a leveldb file, store the type of the file in *type. 71 | // The number encoded in the filename is stored in *number. If the 72 | // filename was successfully parsed, returns true. Else return false. 73 | extern bool ParseFileName(const std::string& filename, 74 | uint64_t* number, 75 | FileType* type); 76 | 77 | // Make the CURRENT file point to the descriptor file with the 78 | // specified number. 79 | extern Status SetCurrentFile(Env* env, const std::string& dbname, 80 | uint64_t descriptor_number); 81 | 82 | 83 | } // namespace leveldb 84 | 85 | #endif // STORAGE_LEVELDB_DB_FILENAME_H_ 86 | -------------------------------------------------------------------------------- /deps/snappy/snappy.gyp: -------------------------------------------------------------------------------- 1 | { 2 | "targets": [{ 3 | "variables": { 4 | "conditions": [ 5 | ["OS=='linux'", {"os_include": "linux"}], 6 | ["OS=='android'", {"os_include": "linux"}], 7 | ["OS=='ios'", {"os_include": "mac"}], 8 | ["OS=='mac'", {"os_include": "mac"}], 9 | ["OS=='solaris'", {"os_include": "solaris"}], 10 | ["OS=='win'", {"os_include": "win32"}], 11 | ["OS=='freebsd'", {"os_include": "freebsd"}], 12 | ["OS=='openbsd'", {"os_include": "openbsd"}] 13 | ] 14 | }, 15 | "target_name": "snappy", 16 | "type": "static_library", 17 | "standalone_static_library": 1, 18 | "include_dirs": [ 19 | "<(os_include)", 20 | "snappy" 21 | ], 22 | "direct_dependent_settings": { 23 | "include_dirs": [ 24 | "<(os_include)", 25 | "snappy" 26 | ] 27 | }, 28 | "defines": [ 29 | "HAVE_CONFIG_H=1" 30 | ], 31 | "conditions": [ 32 | ["OS == 'win'", { 33 | "defines": [ 34 | "_HAS_EXCEPTIONS=0" 35 | ], 36 | "msvs_settings": { 37 | "VCCLCompilerTool": { 38 | "RuntimeTypeInfo": "false", 39 | "EnableFunctionLevelLinking": "true", 40 | "ExceptionHandling": "2", 41 | "DisableSpecificWarnings": [ "4355", "4530" ,"4267", "4244", "4506", "4018" ] 42 | } 43 | } 44 | }], 45 | ["OS == 'linux'", { 46 | "cflags": [ 47 | "-Wno-sign-compare", 48 | "-Wno-unused-function" 49 | ], 50 | "cflags!": [ "-fno-tree-vrp" ] 51 | }], 52 | ["OS == 'freebsd'", { 53 | "cflags": [ 54 | "-Wno-sign-compare", 55 | "-Wno-unused-function" 56 | ] 57 | }], 58 | ["OS == 'openbsd'", { 59 | "cflags": [ 60 | "-Wno-sign-compare", 61 | "-Wno-unused-function" 62 | ] 63 | }], 64 | ["OS == 'solaris'", { 65 | "cflags": [ 66 | "-Wno-sign-compare", 67 | "-Wno-unused-function" 68 | ] 69 | }], 70 | ["OS == 'mac'", { 71 | "xcode_settings": { 72 | "WARNING_CFLAGS": [ 73 | "-Wno-sign-compare", 74 | "-Wno-unused-function" 75 | ], 76 | 77 | # Set minimum target version because we're building on newer 78 | "MACOSX_DEPLOYMENT_TARGET": "10.7", 79 | 80 | # Build universal binary to support M1 (Apple silicon) 81 | "OTHER_CFLAGS": [ 82 | "-arch x86_64", 83 | "-arch arm64" 84 | ] 85 | } 86 | }], 87 | ["OS == 'android'", { 88 | "cflags": [ 89 | "-Wno-sign-compare", 90 | "-fPIC", 91 | "-Wno-unused-function" 92 | ], 93 | "cflags!": [ 94 | "-fno-tree-vrp", 95 | "-mfloat-abi=hard", 96 | "-fPIE" 97 | ] 98 | }], 99 | ["target_arch == 'arm'", { 100 | "cflags": [ 101 | "-mfloat-abi=hard" 102 | ] 103 | }] 104 | ], 105 | "sources": [ 106 | "snappy/snappy-internal.h", 107 | "snappy/snappy-sinksource.cc", 108 | "snappy/snappy-sinksource.h", 109 | "snappy/snappy-stubs-internal.cc", 110 | "snappy/snappy-stubs-internal.h", 111 | "snappy/snappy.cc", 112 | "snappy/snappy.h" 113 | ] 114 | }] 115 | } 116 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 | int allowed_seeks; // Seeks allowed until compaction 20 | uint64_t number; 21 | uint64_t file_size; // File size in bytes 22 | InternalKey smallest; // Smallest internal key served by table 23 | InternalKey largest; // Largest internal key served by table 24 | 25 | FileMetaData() : refs(0), allowed_seeks(1 << 30), file_size(0) { } 26 | }; 27 | 28 | class VersionEdit { 29 | public: 30 | VersionEdit() { Clear(); } 31 | ~VersionEdit() { } 32 | 33 | void Clear(); 34 | 35 | void SetComparatorName(const Slice& name) { 36 | has_comparator_ = true; 37 | comparator_ = name.ToString(); 38 | } 39 | void SetLogNumber(uint64_t num) { 40 | has_log_number_ = true; 41 | log_number_ = num; 42 | } 43 | void SetPrevLogNumber(uint64_t num) { 44 | has_prev_log_number_ = true; 45 | prev_log_number_ = num; 46 | } 47 | void SetNextFile(uint64_t num) { 48 | has_next_file_number_ = true; 49 | next_file_number_ = num; 50 | } 51 | void SetLastSequence(SequenceNumber seq) { 52 | has_last_sequence_ = true; 53 | last_sequence_ = seq; 54 | } 55 | void SetCompactPointer(int level, const InternalKey& key) { 56 | compact_pointers_.push_back(std::make_pair(level, key)); 57 | } 58 | 59 | // Add the specified file at the specified number. 60 | // REQUIRES: This version has not been saved (see VersionSet::SaveTo) 61 | // REQUIRES: "smallest" and "largest" are smallest and largest keys in file 62 | void AddFile(int level, uint64_t file, 63 | uint64_t file_size, 64 | const InternalKey& smallest, 65 | const InternalKey& largest) { 66 | FileMetaData f; 67 | f.number = file; 68 | f.file_size = file_size; 69 | f.smallest = smallest; 70 | f.largest = largest; 71 | new_files_.push_back(std::make_pair(level, f)); 72 | } 73 | 74 | // Delete the specified "file" from the specified "level". 75 | void DeleteFile(int level, uint64_t file) { 76 | deleted_files_.insert(std::make_pair(level, file)); 77 | } 78 | 79 | void EncodeTo(std::string* dst) const; 80 | Status DecodeFrom(const Slice& src); 81 | 82 | std::string DebugString() const; 83 | 84 | private: 85 | friend class VersionSet; 86 | 87 | typedef std::set< std::pair > DeletedFileSet; 88 | 89 | std::string comparator_; 90 | uint64_t log_number_; 91 | uint64_t prev_log_number_; 92 | uint64_t next_file_number_; 93 | SequenceNumber last_sequence_; 94 | bool has_comparator_; 95 | bool has_log_number_; 96 | bool has_prev_log_number_; 97 | bool has_next_file_number_; 98 | bool has_last_sequence_; 99 | 100 | std::vector< std::pair > compact_pointers_; 101 | DeletedFileSet deleted_files_; 102 | std::vector< std::pair > new_files_; 103 | }; 104 | 105 | } // namespace leveldb 106 | 107 | #endif // STORAGE_LEVELDB_DB_VERSION_EDIT_H_ 108 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 | static void InitTypeCrc(uint32_t* type_crc) { 16 | for (int i = 0; i <= kMaxRecordType; i++) { 17 | char t = static_cast(i); 18 | type_crc[i] = crc32c::Value(&t, 1); 19 | } 20 | } 21 | 22 | Writer::Writer(WritableFile* dest) 23 | : dest_(dest), 24 | block_offset_(0) { 25 | InitTypeCrc(type_crc_); 26 | } 27 | 28 | Writer::Writer(WritableFile* dest, uint64_t dest_length) 29 | : dest_(dest), block_offset_(dest_length % kBlockSize) { 30 | InitTypeCrc(type_crc_); 31 | } 32 | 33 | Writer::~Writer() { 34 | } 35 | 36 | Status Writer::AddRecord(const Slice& slice) { 37 | const char* ptr = slice.data(); 38 | size_t left = slice.size(); 39 | 40 | // Fragment the record if necessary and emit it. Note that if slice 41 | // is empty, we still want to iterate once to emit a single 42 | // zero-length record 43 | Status s; 44 | bool begin = true; 45 | do { 46 | const int leftover = kBlockSize - block_offset_; 47 | assert(leftover >= 0); 48 | if (leftover < kHeaderSize) { 49 | // Switch to a new block 50 | if (leftover > 0) { 51 | // Fill the trailer (literal below relies on kHeaderSize being 7) 52 | assert(kHeaderSize == 7); 53 | dest_->Append(Slice("\x00\x00\x00\x00\x00\x00", leftover)); 54 | } 55 | block_offset_ = 0; 56 | } 57 | 58 | // Invariant: we never leave < kHeaderSize bytes in a block. 59 | assert(kBlockSize - block_offset_ - kHeaderSize >= 0); 60 | 61 | const size_t avail = kBlockSize - block_offset_ - kHeaderSize; 62 | const size_t fragment_length = (left < avail) ? left : avail; 63 | 64 | RecordType type; 65 | const bool end = (left == fragment_length); 66 | if (begin && end) { 67 | type = kFullType; 68 | } else if (begin) { 69 | type = kFirstType; 70 | } else if (end) { 71 | type = kLastType; 72 | } else { 73 | type = kMiddleType; 74 | } 75 | 76 | s = EmitPhysicalRecord(type, ptr, fragment_length); 77 | ptr += fragment_length; 78 | left -= fragment_length; 79 | begin = false; 80 | } while (s.ok() && left > 0); 81 | return s; 82 | } 83 | 84 | Status Writer::EmitPhysicalRecord(RecordType t, const char* ptr, size_t n) { 85 | assert(n <= 0xffff); // Must fit in two bytes 86 | assert(block_offset_ + kHeaderSize + n <= kBlockSize); 87 | 88 | // Format the header 89 | char buf[kHeaderSize]; 90 | buf[4] = static_cast(n & 0xff); 91 | buf[5] = static_cast(n >> 8); 92 | buf[6] = static_cast(t); 93 | 94 | // Compute the crc of the record type and the payload. 95 | uint32_t crc = crc32c::Extend(type_crc_[t], ptr, n); 96 | crc = crc32c::Mask(crc); // Adjust for storage 97 | EncodeFixed32(buf, crc); 98 | 99 | // Write the header and the payload 100 | Status s = dest_->Append(Slice(buf, kHeaderSize)); 101 | if (s.ok()) { 102 | s = dest_->Append(Slice(ptr, n)); 103 | if (s.ok()) { 104 | s = dest_->Flush(); 105 | } 106 | } 107 | block_offset_ += kHeaderSize + n; 108 | return s; 109 | } 110 | 111 | } // namespace log 112 | } // namespace leveldb 113 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 | struct BlockContents { 87 | Slice data; // Actual contents of data 88 | bool cachable; // True iff data can be cached 89 | bool heap_allocated; // True iff caller should delete[] data.data() 90 | }; 91 | 92 | // Read the block identified by "handle" from "file". On failure 93 | // return non-OK. On success fill *result and return OK. 94 | extern Status ReadBlock(RandomAccessFile* file, 95 | const ReadOptions& options, 96 | const BlockHandle& handle, 97 | BlockContents* result); 98 | 99 | // Implementation details follow. Clients should ignore, 100 | 101 | inline BlockHandle::BlockHandle() 102 | : offset_(~static_cast(0)), 103 | size_(~static_cast(0)) { 104 | } 105 | 106 | } // namespace leveldb 107 | 108 | #endif // STORAGE_LEVELDB_TABLE_FORMAT_H_ 109 | -------------------------------------------------------------------------------- /deps/leveldb/leveldb-1.20/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 d[0,n-1]. 31 | Slice(const char* d, size_t n) : data_(d), 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 size_t 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 | } // namespace leveldb 107 | 108 | 109 | #endif // STORAGE_LEVELDB_INCLUDE_SLICE_H_ 110 | -------------------------------------------------------------------------------- /deps/snappy/mac/snappy-stubs-public.h: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All Rights Reserved. 2 | // Author: sesse@google.com (Steinar H. Gunderson) 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Various type stubs for the open-source version of Snappy. 31 | // 32 | // This file cannot include config.h, as it is included from snappy.h, 33 | // which is a public header. Instead, snappy-stubs-public.h is generated by 34 | // from snappy-stubs-public.h.in at configure time. 35 | 36 | #ifndef THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_ 37 | #define THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_ 38 | 39 | #if 1 40 | #include 41 | #endif 42 | 43 | #if 1 44 | #include 45 | #endif 46 | 47 | #if 1 48 | #include 49 | #endif 50 | 51 | #define SNAPPY_MAJOR 1 52 | #define SNAPPY_MINOR 1 53 | #define SNAPPY_PATCHLEVEL 4 54 | #define SNAPPY_VERSION \ 55 | ((SNAPPY_MAJOR << 16) | (SNAPPY_MINOR << 8) | SNAPPY_PATCHLEVEL) 56 | 57 | #include 58 | 59 | namespace snappy { 60 | 61 | #if 1 62 | typedef int8_t int8; 63 | typedef uint8_t uint8; 64 | typedef int16_t int16; 65 | typedef uint16_t uint16; 66 | typedef int32_t int32; 67 | typedef uint32_t uint32; 68 | typedef int64_t int64; 69 | typedef uint64_t uint64; 70 | #else 71 | typedef signed char int8; 72 | typedef unsigned char uint8; 73 | typedef short int16; 74 | typedef unsigned short uint16; 75 | typedef int int32; 76 | typedef unsigned int uint32; 77 | typedef long long int64; 78 | typedef unsigned long long uint64; 79 | #endif 80 | 81 | typedef std::string string; 82 | 83 | #ifndef DISALLOW_COPY_AND_ASSIGN 84 | #define DISALLOW_COPY_AND_ASSIGN(TypeName) \ 85 | TypeName(const TypeName&); \ 86 | void operator=(const TypeName&) 87 | #endif 88 | 89 | #if !1 90 | // Windows does not have an iovec type, yet the concept is universally useful. 91 | // It is simple to define it ourselves, so we put it inside our own namespace. 92 | struct iovec { 93 | void* iov_base; 94 | size_t iov_len; 95 | }; 96 | #endif 97 | 98 | } // namespace snappy 99 | 100 | #endif // THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_ 101 | -------------------------------------------------------------------------------- /deps/snappy/freebsd/snappy-stubs-public.h: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All Rights Reserved. 2 | // Author: sesse@google.com (Steinar H. Gunderson) 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Various type stubs for the open-source version of Snappy. 31 | // 32 | // This file cannot include config.h, as it is included from snappy.h, 33 | // which is a public header. Instead, snappy-stubs-public.h is generated by 34 | // from snappy-stubs-public.h.in at configure time. 35 | 36 | #ifndef THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_ 37 | #define THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_ 38 | 39 | #if 1 40 | #include 41 | #endif 42 | 43 | #if 1 44 | #include 45 | #endif 46 | 47 | #if 1 48 | #include 49 | #endif 50 | 51 | #define SNAPPY_MAJOR 1 52 | #define SNAPPY_MINOR 1 53 | #define SNAPPY_PATCHLEVEL 4 54 | #define SNAPPY_VERSION \ 55 | ((SNAPPY_MAJOR << 16) | (SNAPPY_MINOR << 8) | SNAPPY_PATCHLEVEL) 56 | 57 | #include 58 | 59 | namespace snappy { 60 | 61 | #if 1 62 | typedef int8_t int8; 63 | typedef uint8_t uint8; 64 | typedef int16_t int16; 65 | typedef uint16_t uint16; 66 | typedef int32_t int32; 67 | typedef uint32_t uint32; 68 | typedef int64_t int64; 69 | typedef uint64_t uint64; 70 | #else 71 | typedef signed char int8; 72 | typedef unsigned char uint8; 73 | typedef short int16; 74 | typedef unsigned short uint16; 75 | typedef int int32; 76 | typedef unsigned int uint32; 77 | typedef long long int64; 78 | typedef unsigned long long uint64; 79 | #endif 80 | 81 | typedef std::string string; 82 | 83 | #ifndef DISALLOW_COPY_AND_ASSIGN 84 | #define DISALLOW_COPY_AND_ASSIGN(TypeName) \ 85 | TypeName(const TypeName&); \ 86 | void operator=(const TypeName&) 87 | #endif 88 | 89 | #if !1 90 | // Windows does not have an iovec type, yet the concept is universally useful. 91 | // It is simple to define it ourselves, so we put it inside our own namespace. 92 | struct iovec { 93 | void* iov_base; 94 | size_t iov_len; 95 | }; 96 | #endif 97 | 98 | } // namespace snappy 99 | 100 | #endif // THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_ 101 | -------------------------------------------------------------------------------- /deps/snappy/linux/snappy-stubs-public.h: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All Rights Reserved. 2 | // Author: sesse@google.com (Steinar H. Gunderson) 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Various type stubs for the open-source version of Snappy. 31 | // 32 | // This file cannot include config.h, as it is included from snappy.h, 33 | // which is a public header. Instead, snappy-stubs-public.h is generated by 34 | // from snappy-stubs-public.h.in at configure time. 35 | 36 | #ifndef THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_ 37 | #define THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_ 38 | 39 | #if 1 40 | #include 41 | #endif 42 | 43 | #if 1 44 | #include 45 | #endif 46 | 47 | #if 1 48 | #include 49 | #endif 50 | 51 | #define SNAPPY_MAJOR 1 52 | #define SNAPPY_MINOR 1 53 | #define SNAPPY_PATCHLEVEL 4 54 | #define SNAPPY_VERSION \ 55 | ((SNAPPY_MAJOR << 16) | (SNAPPY_MINOR << 8) | SNAPPY_PATCHLEVEL) 56 | 57 | #include 58 | 59 | namespace snappy { 60 | 61 | #if 1 62 | typedef int8_t int8; 63 | typedef uint8_t uint8; 64 | typedef int16_t int16; 65 | typedef uint16_t uint16; 66 | typedef int32_t int32; 67 | typedef uint32_t uint32; 68 | typedef int64_t int64; 69 | typedef uint64_t uint64; 70 | #else 71 | typedef signed char int8; 72 | typedef unsigned char uint8; 73 | typedef short int16; 74 | typedef unsigned short uint16; 75 | typedef int int32; 76 | typedef unsigned int uint32; 77 | typedef long long int64; 78 | typedef unsigned long long uint64; 79 | #endif 80 | 81 | typedef std::string string; 82 | 83 | #ifndef DISALLOW_COPY_AND_ASSIGN 84 | #define DISALLOW_COPY_AND_ASSIGN(TypeName) \ 85 | TypeName(const TypeName&); \ 86 | void operator=(const TypeName&) 87 | #endif 88 | 89 | #if !1 90 | // Windows does not have an iovec type, yet the concept is universally useful. 91 | // It is simple to define it ourselves, so we put it inside our own namespace. 92 | struct iovec { 93 | void* iov_base; 94 | size_t iov_len; 95 | }; 96 | #endif 97 | 98 | } // namespace snappy 99 | 100 | #endif // THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_ 101 | -------------------------------------------------------------------------------- /deps/snappy/openbsd/snappy-stubs-public.h: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All Rights Reserved. 2 | // Author: sesse@google.com (Steinar H. Gunderson) 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Various type stubs for the open-source version of Snappy. 31 | // 32 | // This file cannot include config.h, as it is included from snappy.h, 33 | // which is a public header. Instead, snappy-stubs-public.h is generated by 34 | // from snappy-stubs-public.h.in at configure time. 35 | 36 | #ifndef THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_ 37 | #define THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_ 38 | 39 | #if 1 40 | #include 41 | #endif 42 | 43 | #if 1 44 | #include 45 | #endif 46 | 47 | #if 1 48 | #include 49 | #endif 50 | 51 | #define SNAPPY_MAJOR 1 52 | #define SNAPPY_MINOR 1 53 | #define SNAPPY_PATCHLEVEL 4 54 | #define SNAPPY_VERSION \ 55 | ((SNAPPY_MAJOR << 16) | (SNAPPY_MINOR << 8) | SNAPPY_PATCHLEVEL) 56 | 57 | #include 58 | 59 | namespace snappy { 60 | 61 | #if 1 62 | typedef int8_t int8; 63 | typedef uint8_t uint8; 64 | typedef int16_t int16; 65 | typedef uint16_t uint16; 66 | typedef int32_t int32; 67 | typedef uint32_t uint32; 68 | typedef int64_t int64; 69 | typedef uint64_t uint64; 70 | #else 71 | typedef signed char int8; 72 | typedef unsigned char uint8; 73 | typedef short int16; 74 | typedef unsigned short uint16; 75 | typedef int int32; 76 | typedef unsigned int uint32; 77 | typedef long long int64; 78 | typedef unsigned long long uint64; 79 | #endif 80 | 81 | typedef std::string string; 82 | 83 | #ifndef DISALLOW_COPY_AND_ASSIGN 84 | #define DISALLOW_COPY_AND_ASSIGN(TypeName) \ 85 | TypeName(const TypeName&); \ 86 | void operator=(const TypeName&) 87 | #endif 88 | 89 | #if !1 90 | // Windows does not have an iovec type, yet the concept is universally useful. 91 | // It is simple to define it ourselves, so we put it inside our own namespace. 92 | struct iovec { 93 | void* iov_base; 94 | size_t iov_len; 95 | }; 96 | #endif 97 | 98 | } // namespace snappy 99 | 100 | #endif // THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_ 101 | -------------------------------------------------------------------------------- /deps/snappy/solaris/snappy-stubs-public.h: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All Rights Reserved. 2 | // Author: sesse@google.com (Steinar H. Gunderson) 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Various type stubs for the open-source version of Snappy. 31 | // 32 | // This file cannot include config.h, as it is included from snappy.h, 33 | // which is a public header. Instead, snappy-stubs-public.h is generated by 34 | // from snappy-stubs-public.h.in at configure time. 35 | 36 | #ifndef THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_ 37 | #define THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_ 38 | 39 | #if 1 40 | #include 41 | #endif 42 | 43 | #if 1 44 | #include 45 | #endif 46 | 47 | #if 1 48 | #include 49 | #endif 50 | 51 | #define SNAPPY_MAJOR 1 52 | #define SNAPPY_MINOR 1 53 | #define SNAPPY_PATCHLEVEL 4 54 | #define SNAPPY_VERSION \ 55 | ((SNAPPY_MAJOR << 16) | (SNAPPY_MINOR << 8) | SNAPPY_PATCHLEVEL) 56 | 57 | #include 58 | 59 | namespace snappy { 60 | 61 | #if 1 62 | typedef int8_t int8; 63 | typedef uint8_t uint8; 64 | typedef int16_t int16; 65 | typedef uint16_t uint16; 66 | typedef int32_t int32; 67 | typedef uint32_t uint32; 68 | typedef int64_t int64; 69 | typedef uint64_t uint64; 70 | #else 71 | typedef signed char int8; 72 | typedef unsigned char uint8; 73 | typedef short int16; 74 | typedef unsigned short uint16; 75 | typedef int int32; 76 | typedef unsigned int uint32; 77 | typedef long long int64; 78 | typedef unsigned long long uint64; 79 | #endif 80 | 81 | typedef std::string string; 82 | 83 | #ifndef DISALLOW_COPY_AND_ASSIGN 84 | #define DISALLOW_COPY_AND_ASSIGN(TypeName) \ 85 | TypeName(const TypeName&); \ 86 | void operator=(const TypeName&) 87 | #endif 88 | 89 | #if !1 90 | // Windows does not have an iovec type, yet the concept is universally useful. 91 | // It is simple to define it ourselves, so we put it inside our own namespace. 92 | struct iovec { 93 | void* iov_base; 94 | size_t iov_len; 95 | }; 96 | #endif 97 | 98 | } // namespace snappy 99 | 100 | #endif // THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_ 101 | -------------------------------------------------------------------------------- /deps/snappy/win32/snappy-stubs-public.h: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All Rights Reserved. 2 | // Author: sesse@google.com (Steinar H. Gunderson) 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Various type stubs for the open-source version of Snappy. 31 | // 32 | // This file cannot include config.h, as it is included from snappy.h, 33 | // which is a public header. Instead, snappy-stubs-public.h is generated by 34 | // from snappy-stubs-public.h.in at configure time. 35 | 36 | #ifndef THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_ 37 | #define THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_ 38 | 39 | #if 0 40 | #include 41 | #endif 42 | 43 | #if 1 44 | #include 45 | #endif 46 | 47 | #if 0 48 | #include 49 | #endif 50 | 51 | #define SNAPPY_MAJOR 1 52 | #define SNAPPY_MINOR 1 53 | #define SNAPPY_PATCHLEVEL 4 54 | #define SNAPPY_VERSION \ 55 | ((SNAPPY_MAJOR << 16) | (SNAPPY_MINOR << 8) | SNAPPY_PATCHLEVEL) 56 | 57 | #include 58 | 59 | namespace snappy { 60 | 61 | #if 0 62 | typedef int8_t int8; 63 | typedef uint8_t uint8; 64 | typedef int16_t int16; 65 | typedef uint16_t uint16; 66 | typedef int32_t int32; 67 | typedef uint32_t uint32; 68 | typedef int64_t int64; 69 | typedef uint64_t uint64; 70 | #else 71 | typedef signed char int8; 72 | typedef unsigned char uint8; 73 | typedef short int16; 74 | typedef unsigned short uint16; 75 | typedef int int32; 76 | typedef unsigned int uint32; 77 | typedef long long int64; 78 | typedef unsigned long long uint64; 79 | #endif 80 | 81 | typedef std::string string; 82 | 83 | #ifndef DISALLOW_COPY_AND_ASSIGN 84 | #define DISALLOW_COPY_AND_ASSIGN(TypeName) \ 85 | TypeName(const TypeName&); \ 86 | void operator=(const TypeName&) 87 | #endif 88 | 89 | #if !0 90 | // Windows does not have an iovec type, yet the concept is universally useful. 91 | // It is simple to define it ourselves, so we put it inside our own namespace. 92 | struct iovec { 93 | void* iov_base; 94 | size_t iov_len; 95 | }; 96 | #endif 97 | 98 | } // namespace snappy 99 | 100 | #endif // THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_ 101 | -------------------------------------------------------------------------------- /test/iterator-test.js: -------------------------------------------------------------------------------- 1 | const make = require('./make') 2 | 3 | // This test isn't included in abstract-leveldown because 4 | // the empty-check is currently performed by leveldown. 5 | make('iterator#seek throws if target is empty', function (db, t, done) { 6 | const targets = ['', Buffer.alloc(0), []] 7 | let pending = targets.length 8 | 9 | targets.forEach(function (target) { 10 | const ite = db.iterator() 11 | let error 12 | 13 | try { 14 | ite.seek(target) 15 | } catch (err) { 16 | error = err.message 17 | } 18 | 19 | t.is(error, 'cannot seek() to an empty target', 'got error') 20 | ite.end(end) 21 | }) 22 | 23 | function end (err) { 24 | t.ifError(err, 'no error from end()') 25 | if (!--pending) done() 26 | } 27 | }) 28 | 29 | make('iterator optimized for seek', function (db, t, done) { 30 | const batch = db.batch() 31 | batch.put('a', 1) 32 | batch.put('b', 1) 33 | batch.put('c', 1) 34 | batch.put('d', 1) 35 | batch.put('e', 1) 36 | batch.put('f', 1) 37 | batch.put('g', 1) 38 | batch.write(function (err) { 39 | const ite = db.iterator() 40 | t.ifError(err, 'no error from batch()') 41 | ite.next(function (err, key, value) { 42 | t.ifError(err, 'no error from next()') 43 | t.equal(key.toString(), 'a', 'key matches') 44 | t.equal(ite.cache.length, 0, 'no cache') 45 | ite.next(function (err, key, value) { 46 | t.ifError(err, 'no error from next()') 47 | t.equal(key.toString(), 'b', 'key matches') 48 | t.ok(ite.cache.length > 0, 'has cached items') 49 | ite.seek('d') 50 | t.notOk(ite.cache, 'cache is removed') 51 | ite.next(function (err, key, value) { 52 | t.ifError(err, 'no error from next()') 53 | t.equal(key.toString(), 'd', 'key matches') 54 | t.equal(ite.cache.length, 0, 'no cache') 55 | ite.next(function (err, key, value) { 56 | t.ifError(err, 'no error from next()') 57 | t.equal(key.toString(), 'e', 'key matches') 58 | t.ok(ite.cache.length > 0, 'has cached items') 59 | ite.end(done) 60 | }) 61 | }) 62 | }) 63 | }) 64 | }) 65 | }) 66 | 67 | make('close db with open iterator', function (db, t, done) { 68 | const ite = db.iterator() 69 | let cnt = 0 70 | let hadError = false 71 | 72 | ite.next(function loop (err, key, value) { 73 | if (cnt++ === 0) { 74 | // The first call should succeed, because it was scheduled before close() 75 | t.ifError(err, 'no error from next()') 76 | } else { 77 | // The second call should fail, because it was scheduled after close() 78 | t.equal(err.message, 'iterator has ended') 79 | hadError = true 80 | } 81 | if (key !== undefined) { ite.next(loop) } 82 | }) 83 | 84 | db.close(function (err) { 85 | t.ifError(err, 'no error from close()') 86 | t.ok(hadError) 87 | 88 | done(null, false) 89 | }) 90 | }) 91 | 92 | make('key-only iterator', function (db, t, done) { 93 | const it = db.iterator({ values: false, keyAsBuffer: false, valueAsBuffer: false }) 94 | 95 | it.next(function (err, key, value) { 96 | t.ifError(err, 'no next() error') 97 | t.is(key, 'one') 98 | t.is(value, '') // should this be undefined? 99 | it.end(done) 100 | }) 101 | }) 102 | 103 | make('value-only iterator', function (db, t, done) { 104 | const it = db.iterator({ keys: false, keyAsBuffer: false, valueAsBuffer: false }) 105 | 106 | it.next(function (err, key, value) { 107 | t.ifError(err, 'no next() error') 108 | t.is(key, '') // should this be undefined? 109 | t.is(value, '1') 110 | it.end(done) 111 | }) 112 | }) 113 | --------------------------------------------------------------------------------