├── .gitignore ├── .gitmodules ├── .travis.yml ├── .vscode ├── launch.json └── settings.json ├── BUILD.gn ├── BloomFilter.cpp ├── BloomFilter.h ├── BloomFilterWrap.cpp ├── BloomFilterWrap.h ├── LICENSE ├── Makefile ├── README.md ├── addon.cpp ├── base.h ├── binding.gyp ├── brave └── BUILD.gn ├── hashFn.cpp ├── hashFn.h ├── include.js ├── main.cpp ├── package-lock.json ├── package.json ├── sample └── binding.gyp ├── scripts ├── cpplint.py └── lib │ ├── __init__.py │ ├── config.py │ ├── github.py │ └── util.py └── test ├── binding.gyp ├── test-bloom.cpp ├── test-main.cpp ├── testResult2.h ├── util.cpp └── util.h /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Compiled Dynamic libraries 12 | *.so 13 | *.dylib 14 | *.dll 15 | 16 | # Fortran module files 17 | *.mod 18 | 19 | # Compiled Static libraries 20 | *.lai 21 | *.la 22 | *.a 23 | *.lib 24 | 25 | # Executables 26 | *.exe 27 | *.out 28 | *.app 29 | 30 | build/ 31 | node_modules/ 32 | run 33 | 34 | *.pyc 35 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "vendor/depot_tools"] 2 | path = vendor/depot_tools 3 | url = https://chromium.googlesource.com/chromium/tools/depot_tools.git 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "5.2" 4 | - "node" 5 | addons: 6 | apt: 7 | sources: 8 | - ubuntu-toolchain-r-test 9 | packages: 10 | - gcc-4.8 11 | - g++-4.8 12 | - ninja-build 13 | 14 | env: 15 | - TRAVIS=travis CXX=g++-4.8 16 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.1.0", 3 | // List of configurations. Add new configurations or edit existing ones. 4 | "configurations": [ 5 | { 6 | // Name of configuration; appears in the launch configuration drop down menu. 7 | "name": "Launch app.js", 8 | // Type of configuration. 9 | "type": "node", 10 | // Workspace relative or absolute path to the program. 11 | "program": "app.js", 12 | // Automatically stop program after launch. 13 | "stopOnEntry": false, 14 | // Command line arguments passed to the program. 15 | "args": [], 16 | // Workspace relative or absolute path to the working directory of the program being debugged. Default is the current workspace. 17 | "cwd": ".", 18 | // Workspace relative or absolute path to the runtime executable to be used. Default is the runtime executable on the PATH. 19 | "runtimeExecutable": null, 20 | // Optional arguments passed to the runtime executable. 21 | "runtimeArgs": ["--nolazy"], 22 | // Environment variables passed to the program. 23 | "env": { 24 | "NODE_ENV": "development" 25 | }, 26 | // Use JavaScript source maps (if they exist). 27 | "sourceMaps": false, 28 | // If JavaScript source maps are enabled, the generated code is expected in this directory. 29 | "outDir": null 30 | }, 31 | { 32 | "name": "Attach", 33 | "type": "node", 34 | // TCP/IP address. Default is "localhost". 35 | "address": "localhost", 36 | // Port to attach to. 37 | "port": 5858, 38 | "sourceMaps": false 39 | } 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | } -------------------------------------------------------------------------------- /BUILD.gn: -------------------------------------------------------------------------------- 1 | config("external_config") { 2 | include_dirs = [ "." ] 3 | } 4 | 5 | source_set("bloom-filter-cpp") { 6 | public_configs = [ ":external_config" ] 7 | 8 | sources = [ 9 | "BloomFilter.cpp", 10 | "BloomFilter.h", 11 | "hashFn.cpp", 12 | "hashFn.h", 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /BloomFilter.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 Brian R. Bondy. Distributed under the MPL2 license. 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 | 6 | #include 7 | #include "BloomFilter.h" 8 | 9 | BloomFilter::BloomFilter(unsigned int bitsPerElement, 10 | unsigned int estimatedNumElements, HashFn *hashFns, int numHashFns) : 11 | hashFns(nullptr), numHashFns(0), byteBufferSize(0), buffer(nullptr) { 12 | this->hashFns = hashFns; 13 | this->numHashFns = numHashFns; 14 | lastHashes = new uint64_t[numHashFns]; 15 | byteBufferSize = bitsPerElement * estimatedNumElements / 8 + 1; 16 | bitBufferSize = byteBufferSize * 8; 17 | buffer = new char[byteBufferSize]; 18 | memset(buffer, 0, byteBufferSize); 19 | } 20 | 21 | // Constructs a BloomFilter by copying the specified buffer and number of bytes 22 | BloomFilter::BloomFilter(const char *buffer, int byteBufferSize, 23 | HashFn *hashFns, int numHashFns) : 24 | hashFns(nullptr), numHashFns(0), byteBufferSize(0), buffer(nullptr) { 25 | this->hashFns = hashFns; 26 | this->numHashFns = numHashFns; 27 | lastHashes = new uint64_t[numHashFns]; 28 | this->byteBufferSize = byteBufferSize; 29 | bitBufferSize = byteBufferSize * 8; 30 | this->buffer = new char[byteBufferSize]; 31 | memcpy(this->buffer, buffer, byteBufferSize); 32 | } 33 | 34 | BloomFilter::~BloomFilter() { 35 | if (buffer) { 36 | delete[] buffer; 37 | } 38 | if (lastHashes) { 39 | delete[] lastHashes; 40 | } 41 | } 42 | 43 | void BloomFilter::setBit(unsigned int bitLocation) { 44 | buffer[bitLocation / 8] |= 1 << bitLocation % 8; 45 | } 46 | 47 | bool BloomFilter::isBitSet(unsigned int bitLocation) { 48 | return !!(buffer[bitLocation / 8] & 1 << bitLocation % 8); 49 | } 50 | 51 | void BloomFilter::add(const char *input, int len) { 52 | for (int j = 0; j < numHashFns; j++) { 53 | setBit(hashFns[j](input, len) % bitBufferSize); 54 | } 55 | } 56 | 57 | void BloomFilter::add(const char *sz) { 58 | add(sz, static_cast(strlen(sz))); 59 | } 60 | 61 | bool BloomFilter::exists(const char *input, int len) { 62 | bool allSet = true; 63 | for (int j = 0; j < numHashFns; j++) { 64 | allSet = allSet && isBitSet(hashFns[j](input, len) % bitBufferSize); 65 | } 66 | return allSet; 67 | } 68 | 69 | bool BloomFilter::exists(const char *sz) { 70 | return exists(sz, static_cast(strlen(sz))); 71 | } 72 | 73 | void BloomFilter::getHashesForCharCodes(const char *input, int inputLen, 74 | uint64_t *lastHashes, uint64_t *newHashes, unsigned char lastCharCode) { 75 | for (int i = 0; i < numHashFns; i++) { 76 | if (lastHashes) { 77 | *(newHashes + i) = hashFns[i](input, inputLen, 78 | lastCharCode, *(lastHashes+i)); 79 | } else { 80 | *(newHashes + i) = hashFns[i](input, inputLen); 81 | } 82 | } 83 | } 84 | 85 | bool BloomFilter::substringExists(const char *data, int dataLen, 86 | int substringLength) { 87 | unsigned char lastCharCode = 0; 88 | for (int i = 0; i < dataLen - substringLength + 1; i++) { 89 | getHashesForCharCodes(data + i, substringLength, i == 0 90 | ? nullptr : lastHashes, lastHashes, lastCharCode); 91 | bool allSet = true; 92 | for (int j = 0; j < numHashFns; j++) { 93 | allSet = allSet && isBitSet(lastHashes[j] % bitBufferSize); 94 | } 95 | if (allSet) { 96 | return true; 97 | } 98 | lastCharCode = data[i]; 99 | } 100 | return false; 101 | } 102 | 103 | bool BloomFilter::substringExists(const char *data, int substringLength) { 104 | return substringExists(data, static_cast(strlen(data)), substringLength); 105 | } 106 | 107 | void BloomFilter::clear() { 108 | memset(buffer, 0, byteBufferSize); 109 | } 110 | -------------------------------------------------------------------------------- /BloomFilter.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 Brian R. Bondy. Distributed under the MPL2 license. 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 | 6 | #ifndef BLOOMFILTER_H_ 7 | #define BLOOMFILTER_H_ 8 | 9 | #include 10 | #include 11 | #include "./hashFn.h" 12 | #include "./base.h" 13 | 14 | static HashFn h1(13); 15 | static HashFn h2(17); 16 | static HashFn h3(31); 17 | static HashFn h4(41); 18 | static HashFn h5(53); 19 | static HashFn defaultHashFns[5] = {h1, h2, h3, h4, h5}; 20 | 21 | 22 | /** 23 | * Implements a Bloom Filter using Rabin Karp for char* buffer lookups 24 | */ 25 | class BloomFilter { 26 | public: 27 | BloomFilter(unsigned int bitsPerElement = 10, 28 | unsigned int estimatedNumElements = 50000, 29 | HashFn hashFns[] = defaultHashFns, 30 | int numHashFns = sizeof(defaultHashFns)/sizeof(defaultHashFns[0])); 31 | BloomFilter(const char *buffer, int byteBufferSize, 32 | HashFn hashFns[] = defaultHashFns, 33 | int numHashFns = sizeof(defaultHashFns)/sizeof(defaultHashFns[0])); 34 | virtual ~BloomFilter(); 35 | // Sets the specified bit in the buffer 36 | void setBit(unsigned int bitLocation); 37 | // Checks if the specified bit is set in the buffer 38 | bool isBitSet(unsigned int bitLocation); 39 | // Adds the specified buffer to the bloom filter 40 | void add(const char *input, int len); 41 | void add(const char *sz); 42 | // Empty the Bloom Filter 43 | void clear(); 44 | 45 | /** 46 | * Checks whether an element probably exists in the set, or definitely 47 | * doesn't. 48 | * @param sz Either a string to check for existance or an array of the 49 | * string's char codes. The main reason why you'd want to pass in a char 50 | * code array is because passing a string will use JS directly to get 51 | * the char codes which is very inneficient compared to calling into C++ 52 | * code to get it and then making the call. 53 | * 54 | * Returns true if the element probably exists in the set 55 | * Returns false if the element definitely does not exist in the set 56 | */ 57 | bool exists(const char *input, int len); 58 | bool exists(const char *sz); 59 | 60 | /** 61 | * Checks if any substring of length substringLength probably exists or 62 | * definitely doesn't. If false is returned then no substring of the 63 | * specified string of the specified length is in the bloom filter 64 | * 65 | * @param data The substring or char array to check substrings on. 66 | */ 67 | bool substringExists(const char *data, int dataLen, int substringLength); 68 | bool substringExists(const char *sz, int substringLength); 69 | 70 | /** 71 | * Obtains the buffer used as the bloom filter data 72 | */ 73 | const char * getBuffer() { 74 | return buffer; 75 | } 76 | 77 | /** 78 | * Obtains the Bloom Filter's buffer size in bytes 79 | */ 80 | int getByteBufferSize() { 81 | return byteBufferSize; 82 | } 83 | 84 | private: 85 | HashFn *hashFns; 86 | uint64_t *lastHashes; 87 | int numHashFns; 88 | unsigned int byteBufferSize; 89 | unsigned int bitBufferSize; 90 | char *buffer; 91 | 92 | /** 93 | * Obtains the hashes for the specified charCodes 94 | * See "Rabin fingerprint" in 95 | * https://en.wikipedia.org/wiki/Rabin%E2%80%93Karp_algorithm 96 | * for more information. 97 | * 98 | * @param charCodes An array of the char codes to use for the hash 99 | * @param lastHashes Input and output for the last hash value 100 | * function for a faster computation. Must be called with lastCharCode but 101 | * can be nullptr otherwise. 102 | * 103 | * @param newHashses fills in the corresponding new hashes, can be the same 104 | * as lastHashes 105 | * @param lastCharCode if specified, it will pass the last char code 106 | * to the hashing function for a faster computation. Must be called 107 | * with lastHashes. 108 | */ 109 | void getHashesForCharCodes(const char *input, int inputLen, 110 | uint64_t *lastHashes, uint64_t *newHashes, unsigned char lastCharCode); 111 | }; 112 | 113 | #endif // BLOOMFILTER_H_ 114 | -------------------------------------------------------------------------------- /BloomFilterWrap.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 Brian R. Bondy. Distributed under the MPL2 license. 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 | 6 | #include "BloomFilterWrap.h" 7 | 8 | namespace BloomFilterWrap { 9 | 10 | using v8::Context; 11 | using v8::Function; 12 | using v8::FunctionCallbackInfo; 13 | using v8::FunctionTemplate; 14 | using v8::Isolate; 15 | using v8::Local; 16 | using v8::Number; 17 | using v8::Object; 18 | using v8::Persistent; 19 | using v8::String; 20 | using v8::Boolean; 21 | using v8::Value; 22 | 23 | Persistent BloomFilterWrap::constructor; 24 | 25 | BloomFilterWrap::BloomFilterWrap(unsigned int bitsPerElement, 26 | unsigned int estimatedNumElements, HashFn hashFns[], int numHashFns) 27 | : BloomFilter(bitsPerElement, estimatedNumElements, hashFns, numHashFns) { 28 | } 29 | 30 | BloomFilterWrap::~BloomFilterWrap() { 31 | } 32 | 33 | void BloomFilterWrap::Init(Local exports) { 34 | Isolate* isolate = exports->GetIsolate(); 35 | 36 | // Prepare constructor template 37 | Local tpl = FunctionTemplate::New(isolate, New); 38 | tpl->SetClassName(String::NewFromUtf8(isolate, "BloomFilter")); 39 | tpl->InstanceTemplate()->SetInternalFieldCount(1); 40 | 41 | // Prototype 42 | NODE_SET_PROTOTYPE_METHOD(tpl, "add", BloomFilterWrap::Add); 43 | NODE_SET_PROTOTYPE_METHOD(tpl, "exists", BloomFilterWrap::Exists); 44 | 45 | constructor.Reset(isolate, tpl->GetFunction( 46 | isolate->GetCurrentContext()).ToLocalChecked()); 47 | exports->Set(String::NewFromUtf8(isolate, "BloomFilter"), 48 | tpl->GetFunction(isolate->GetCurrentContext()).ToLocalChecked()); 49 | } 50 | 51 | void BloomFilterWrap::New(const FunctionCallbackInfo& args) { 52 | Isolate* isolate = args.GetIsolate(); 53 | 54 | if (args.IsConstructCall()) { 55 | // Invoked as constructor: `new BloomFilter(...)` 56 | BloomFilterWrap* obj = new BloomFilterWrap(); 57 | obj->Wrap(args.This()); 58 | args.GetReturnValue().Set(args.This()); 59 | } else { 60 | // Invoked as plain function `BloomFilter(...)`, turn into construct call. 61 | const int argc = 1; 62 | Local argv[argc] = { args[0] }; 63 | Local context = isolate->GetCurrentContext(); 64 | Local cons = Local::New(isolate, constructor); 65 | Local result = 66 | cons->NewInstance(context, argc, argv).ToLocalChecked(); 67 | args.GetReturnValue().Set(result); 68 | } 69 | } 70 | 71 | void BloomFilterWrap::Add(const FunctionCallbackInfo& args) { 72 | Isolate* isolate = args.GetIsolate(); 73 | String::Utf8Value str(isolate, args[0]->ToString(isolate->GetCurrentContext()) 74 | .FromMaybe(v8::Local())); 75 | const char * buffer = *str; 76 | 77 | BloomFilterWrap* obj = ObjectWrap::Unwrap(args.Holder()); 78 | obj->add(buffer); 79 | } 80 | 81 | void BloomFilterWrap::Exists(const FunctionCallbackInfo& args) { 82 | Isolate* isolate = args.GetIsolate(); 83 | String::Utf8Value str(isolate, args[0]->ToString(isolate->GetCurrentContext()) 84 | .FromMaybe(v8::Local())); 85 | const char * buffer = *str; 86 | 87 | BloomFilterWrap* obj = ObjectWrap::Unwrap(args.Holder()); 88 | bool exists = obj->exists(buffer); 89 | 90 | args.GetReturnValue().Set(Boolean::New(isolate, exists)); 91 | } 92 | 93 | 94 | } // namespace BloomFilterWrap 95 | -------------------------------------------------------------------------------- /BloomFilterWrap.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 Brian R. Bondy. Distributed under the MPL2 license. 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 | 6 | #ifndef BLOOMFILTERWRAP_H_ 7 | #define BLOOMFILTERWRAP_H_ 8 | 9 | #include 10 | #include 11 | 12 | #include "BloomFilter.h" 13 | 14 | namespace BloomFilterWrap { 15 | 16 | /** 17 | * Wraps Bloom Filter for use in Node 18 | */ 19 | class BloomFilterWrap : public BloomFilter, public node::ObjectWrap { 20 | public: 21 | static void Init(v8::Local exports); 22 | 23 | private: 24 | BloomFilterWrap(unsigned int bitsPerElement = 10, 25 | unsigned int estimatedNumElements = 50000, 26 | HashFn hashFns[] = defaultHashFns, 27 | int numHashFns = sizeof(defaultHashFns)/sizeof(defaultHashFns[0])); 28 | virtual ~BloomFilterWrap(); 29 | 30 | static void New(const v8::FunctionCallbackInfo& args); 31 | 32 | static void Add(const v8::FunctionCallbackInfo& args); 33 | static void Exists(const v8::FunctionCallbackInfo& args); 34 | 35 | static v8::Persistent constructor; 36 | }; 37 | 38 | } // namespace BloomFilterWrap 39 | 40 | #endif // BLOOMFILTERWRAP_H_ 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Mozilla Public License, version 2.0 2 | 3 | 1. Definitions 4 | 5 | 1.1. "Contributor" 6 | 7 | means each individual or legal entity that creates, contributes to the 8 | creation of, or owns Covered Software. 9 | 10 | 1.2. "Contributor Version" 11 | 12 | means the combination of the Contributions of others (if any) used by a 13 | Contributor and that particular Contributor's Contribution. 14 | 15 | 1.3. "Contribution" 16 | 17 | means Covered Software of a particular Contributor. 18 | 19 | 1.4. "Covered Software" 20 | 21 | means Source Code Form to which the initial Contributor has attached the 22 | notice in Exhibit A, the Executable Form of such Source Code Form, and 23 | Modifications of such Source Code Form, in each case including portions 24 | thereof. 25 | 26 | 1.5. "Incompatible With Secondary Licenses" 27 | means 28 | 29 | a. that the initial Contributor has attached the notice described in 30 | Exhibit B to the Covered Software; or 31 | 32 | b. that the Covered Software was made available under the terms of 33 | version 1.1 or earlier of the License, but not also under the terms of 34 | a Secondary License. 35 | 36 | 1.6. "Executable Form" 37 | 38 | means any form of the work other than Source Code Form. 39 | 40 | 1.7. "Larger Work" 41 | 42 | means a work that combines Covered Software with other material, in a 43 | separate file or files, that is not Covered Software. 44 | 45 | 1.8. "License" 46 | 47 | means this document. 48 | 49 | 1.9. "Licensable" 50 | 51 | means having the right to grant, to the maximum extent possible, whether 52 | at the time of the initial grant or subsequently, any and all of the 53 | rights conveyed by this License. 54 | 55 | 1.10. "Modifications" 56 | 57 | means any of the following: 58 | 59 | a. any file in Source Code Form that results from an addition to, 60 | deletion from, or modification of the contents of Covered Software; or 61 | 62 | b. any new file in Source Code Form that contains any Covered Software. 63 | 64 | 1.11. "Patent Claims" of a Contributor 65 | 66 | means any patent claim(s), including without limitation, method, 67 | process, and apparatus claims, in any patent Licensable by such 68 | Contributor that would be infringed, but for the grant of the License, 69 | by the making, using, selling, offering for sale, having made, import, 70 | or transfer of either its Contributions or its Contributor Version. 71 | 72 | 1.12. "Secondary License" 73 | 74 | means either the GNU General Public License, Version 2.0, the GNU Lesser 75 | General Public License, Version 2.1, the GNU Affero General Public 76 | License, Version 3.0, or any later versions of those licenses. 77 | 78 | 1.13. "Source Code Form" 79 | 80 | means the form of the work preferred for making modifications. 81 | 82 | 1.14. "You" (or "Your") 83 | 84 | means an individual or a legal entity exercising rights under this 85 | License. For legal entities, "You" includes any entity that controls, is 86 | controlled by, or is under common control with You. For purposes of this 87 | definition, "control" means (a) the power, direct or indirect, to cause 88 | the direction or management of such entity, whether by contract or 89 | otherwise, or (b) ownership of more than fifty percent (50%) of the 90 | outstanding shares or beneficial ownership of such entity. 91 | 92 | 93 | 2. License Grants and Conditions 94 | 95 | 2.1. Grants 96 | 97 | Each Contributor hereby grants You a world-wide, royalty-free, 98 | non-exclusive license: 99 | 100 | a. under intellectual property rights (other than patent or trademark) 101 | Licensable by such Contributor to use, reproduce, make available, 102 | modify, display, perform, distribute, and otherwise exploit its 103 | Contributions, either on an unmodified basis, with Modifications, or 104 | as part of a Larger Work; and 105 | 106 | b. under Patent Claims of such Contributor to make, use, sell, offer for 107 | sale, have made, import, and otherwise transfer either its 108 | Contributions or its Contributor Version. 109 | 110 | 2.2. Effective Date 111 | 112 | The licenses granted in Section 2.1 with respect to any Contribution 113 | become effective for each Contribution on the date the Contributor first 114 | distributes such Contribution. 115 | 116 | 2.3. Limitations on Grant Scope 117 | 118 | The licenses granted in this Section 2 are the only rights granted under 119 | this License. No additional rights or licenses will be implied from the 120 | distribution or licensing of Covered Software under this License. 121 | Notwithstanding Section 2.1(b) above, no patent license is granted by a 122 | Contributor: 123 | 124 | a. for any code that a Contributor has removed from Covered Software; or 125 | 126 | b. for infringements caused by: (i) Your and any other third party's 127 | modifications of Covered Software, or (ii) the combination of its 128 | Contributions with other software (except as part of its Contributor 129 | Version); or 130 | 131 | c. under Patent Claims infringed by Covered Software in the absence of 132 | its Contributions. 133 | 134 | This License does not grant any rights in the trademarks, service marks, 135 | or logos of any Contributor (except as may be necessary to comply with 136 | the notice requirements in Section 3.4). 137 | 138 | 2.4. Subsequent Licenses 139 | 140 | No Contributor makes additional grants as a result of Your choice to 141 | distribute the Covered Software under a subsequent version of this 142 | License (see Section 10.2) or under the terms of a Secondary License (if 143 | permitted under the terms of Section 3.3). 144 | 145 | 2.5. Representation 146 | 147 | Each Contributor represents that the Contributor believes its 148 | Contributions are its original creation(s) or it has sufficient rights to 149 | grant the rights to its Contributions conveyed by this License. 150 | 151 | 2.6. Fair Use 152 | 153 | This License is not intended to limit any rights You have under 154 | applicable copyright doctrines of fair use, fair dealing, or other 155 | equivalents. 156 | 157 | 2.7. Conditions 158 | 159 | Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in 160 | Section 2.1. 161 | 162 | 163 | 3. Responsibilities 164 | 165 | 3.1. Distribution of Source Form 166 | 167 | All distribution of Covered Software in Source Code Form, including any 168 | Modifications that You create or to which You contribute, must be under 169 | the terms of this License. You must inform recipients that the Source 170 | Code Form of the Covered Software is governed by the terms of this 171 | License, and how they can obtain a copy of this License. You may not 172 | attempt to alter or restrict the recipients' rights in the Source Code 173 | Form. 174 | 175 | 3.2. Distribution of Executable Form 176 | 177 | If You distribute Covered Software in Executable Form then: 178 | 179 | a. such Covered Software must also be made available in Source Code Form, 180 | as described in Section 3.1, and You must inform recipients of the 181 | Executable Form how they can obtain a copy of such Source Code Form by 182 | reasonable means in a timely manner, at a charge no more than the cost 183 | of distribution to the recipient; and 184 | 185 | b. You may distribute such Executable Form under the terms of this 186 | License, or sublicense it under different terms, provided that the 187 | license for the Executable Form does not attempt to limit or alter the 188 | recipients' rights in the Source Code Form under this License. 189 | 190 | 3.3. Distribution of a Larger Work 191 | 192 | You may create and distribute a Larger Work under terms of Your choice, 193 | provided that You also comply with the requirements of this License for 194 | the Covered Software. If the Larger Work is a combination of Covered 195 | Software with a work governed by one or more Secondary Licenses, and the 196 | Covered Software is not Incompatible With Secondary Licenses, this 197 | License permits You to additionally distribute such Covered Software 198 | under the terms of such Secondary License(s), so that the recipient of 199 | the Larger Work may, at their option, further distribute the Covered 200 | Software under the terms of either this License or such Secondary 201 | License(s). 202 | 203 | 3.4. Notices 204 | 205 | You may not remove or alter the substance of any license notices 206 | (including copyright notices, patent notices, disclaimers of warranty, or 207 | limitations of liability) contained within the Source Code Form of the 208 | Covered Software, except that You may alter any license notices to the 209 | extent required to remedy known factual inaccuracies. 210 | 211 | 3.5. Application of Additional Terms 212 | 213 | You may choose to offer, and to charge a fee for, warranty, support, 214 | indemnity or liability obligations to one or more recipients of Covered 215 | Software. However, You may do so only on Your own behalf, and not on 216 | behalf of any Contributor. You must make it absolutely clear that any 217 | such warranty, support, indemnity, or liability obligation is offered by 218 | You alone, and You hereby agree to indemnify every Contributor for any 219 | liability incurred by such Contributor as a result of warranty, support, 220 | indemnity or liability terms You offer. You may include additional 221 | disclaimers of warranty and limitations of liability specific to any 222 | jurisdiction. 223 | 224 | 4. Inability to Comply Due to Statute or Regulation 225 | 226 | If it is impossible for You to comply with any of the terms of this License 227 | with respect to some or all of the Covered Software due to statute, 228 | judicial order, or regulation then You must: (a) comply with the terms of 229 | this License to the maximum extent possible; and (b) describe the 230 | limitations and the code they affect. Such description must be placed in a 231 | text file included with all distributions of the Covered Software under 232 | this License. Except to the extent prohibited by statute or regulation, 233 | such description must be sufficiently detailed for a recipient of ordinary 234 | skill to be able to understand it. 235 | 236 | 5. Termination 237 | 238 | 5.1. The rights granted under this License will terminate automatically if You 239 | fail to comply with any of its terms. However, if You become compliant, 240 | then the rights granted under this License from a particular Contributor 241 | are reinstated (a) provisionally, unless and until such Contributor 242 | explicitly and finally terminates Your grants, and (b) on an ongoing 243 | basis, if such Contributor fails to notify You of the non-compliance by 244 | some reasonable means prior to 60 days after You have come back into 245 | compliance. Moreover, Your grants from a particular Contributor are 246 | reinstated on an ongoing basis if such Contributor notifies You of the 247 | non-compliance by some reasonable means, this is the first time You have 248 | received notice of non-compliance with this License from such 249 | Contributor, and You become compliant prior to 30 days after Your receipt 250 | of the notice. 251 | 252 | 5.2. If You initiate litigation against any entity by asserting a patent 253 | infringement claim (excluding declaratory judgment actions, 254 | counter-claims, and cross-claims) alleging that a Contributor Version 255 | directly or indirectly infringes any patent, then the rights granted to 256 | You by any and all Contributors for the Covered Software under Section 257 | 2.1 of this License shall terminate. 258 | 259 | 5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user 260 | license agreements (excluding distributors and resellers) which have been 261 | validly granted by You or Your distributors under this License prior to 262 | termination shall survive termination. 263 | 264 | 6. Disclaimer of Warranty 265 | 266 | Covered Software is provided under this License on an "as is" basis, 267 | without warranty of any kind, either expressed, implied, or statutory, 268 | including, without limitation, warranties that the Covered Software is free 269 | of defects, merchantable, fit for a particular purpose or non-infringing. 270 | The entire risk as to the quality and performance of the Covered Software 271 | is with You. Should any Covered Software prove defective in any respect, 272 | You (not any Contributor) assume the cost of any necessary servicing, 273 | repair, or correction. This disclaimer of warranty constitutes an essential 274 | part of this License. No use of any Covered Software is authorized under 275 | this License except under this disclaimer. 276 | 277 | 7. Limitation of Liability 278 | 279 | Under no circumstances and under no legal theory, whether tort (including 280 | negligence), contract, or otherwise, shall any Contributor, or anyone who 281 | distributes Covered Software as permitted above, be liable to You for any 282 | direct, indirect, special, incidental, or consequential damages of any 283 | character including, without limitation, damages for lost profits, loss of 284 | goodwill, work stoppage, computer failure or malfunction, or any and all 285 | other commercial damages or losses, even if such party shall have been 286 | informed of the possibility of such damages. This limitation of liability 287 | shall not apply to liability for death or personal injury resulting from 288 | such party's negligence to the extent applicable law prohibits such 289 | limitation. Some jurisdictions do not allow the exclusion or limitation of 290 | incidental or consequential damages, so this exclusion and limitation may 291 | not apply to You. 292 | 293 | 8. Litigation 294 | 295 | Any litigation relating to this License may be brought only in the courts 296 | of a jurisdiction where the defendant maintains its principal place of 297 | business and such litigation shall be governed by laws of that 298 | jurisdiction, without reference to its conflict-of-law provisions. Nothing 299 | in this Section shall prevent a party's ability to bring cross-claims or 300 | counter-claims. 301 | 302 | 9. Miscellaneous 303 | 304 | This License represents the complete agreement concerning the subject 305 | matter hereof. If any provision of this License is held to be 306 | unenforceable, such provision shall be reformed only to the extent 307 | necessary to make it enforceable. Any law or regulation which provides that 308 | the language of a contract shall be construed against the drafter shall not 309 | be used to construe this License against a Contributor. 310 | 311 | 312 | 10. Versions of the License 313 | 314 | 10.1. New Versions 315 | 316 | Mozilla Foundation is the license steward. Except as provided in Section 317 | 10.3, no one other than the license steward has the right to modify or 318 | publish new versions of this License. Each version will be given a 319 | distinguishing version number. 320 | 321 | 10.2. Effect of New Versions 322 | 323 | You may distribute the Covered Software under the terms of the version 324 | of the License under which You originally received the Covered Software, 325 | or under the terms of any subsequent version published by the license 326 | steward. 327 | 328 | 10.3. Modified Versions 329 | 330 | If you create software not governed by this License, and you want to 331 | create a new license for such software, you may create and use a 332 | modified version of this License if you rename the license and remove 333 | any references to the name of the license steward (except to note that 334 | such modified license differs from this License). 335 | 336 | 10.4. Distributing Source Code Form that is Incompatible With Secondary 337 | Licenses If You choose to distribute Source Code Form that is 338 | Incompatible With Secondary Licenses under the terms of this version of 339 | the License, the notice described in Exhibit B of this License must be 340 | attached. 341 | 342 | Exhibit A - Source Code Form License Notice 343 | 344 | This Source Code Form is subject to the 345 | terms of the Mozilla Public License, v. 346 | 2.0. If a copy of the MPL was not 347 | distributed with this file, You can 348 | obtain one at 349 | http://mozilla.org/MPL/2.0/. 350 | 351 | If it is not possible or desirable to put the notice in a particular file, 352 | then You may include the notice in a location (such as a LICENSE file in a 353 | relevant directory) where a recipient would be likely to look for such a 354 | notice. 355 | 356 | You may add additional accurate notices of copyright ownership. 357 | 358 | Exhibit B - "Incompatible With Secondary Licenses" Notice 359 | 360 | This Source Code Form is "Incompatible 361 | With Secondary Licenses", as defined by 362 | the Mozilla Public License, v. 2.0. 363 | 364 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: build 2 | .PHONY: test 3 | .PHONY: sample 4 | 5 | build: 6 | ./node_modules/.bin/node-gyp rebuild 7 | 8 | test: 9 | cd test 10 | ./node_modules/node-gyp/gyp/gyp_main.py --generator-output=./build --depth=. -f ninja test/binding.gyp 11 | ./node_modules/node-gyp/gyp/gyp_main.py --generator-output=./build --depth=. -f xcode test/binding.gyp 12 | ninja -C ./build/out/Default -f build.ninja 13 | ./build/out/Default/test || [ $$? -eq 0 ] 14 | 15 | sample: 16 | cd sample 17 | ./node_modules/node-gyp/gyp/gyp_main.py --generator-output=./build --depth=. -f ninja sample/binding.gyp 18 | ./node_modules/node-gyp/gyp/gyp_main.py --generator-output=./build --depth=. -f xcode sample/binding.gyp 19 | ninja -C ./build/out/Default -f build.ninja 20 | ./build/out/Default/sample 21 | 22 | clean: 23 | rm -Rf build 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/bbondy/bloom-filter-cpp.svg?branch=master)](https://travis-ci.org/bbondy/bloom-filter-cpp) 2 | 3 | # BloomFilter.cpp 4 | C++ Native node module Bloom filter written in C++ for use in node or any other C++ project. 5 | 6 | The Bloom filter tests whether an element belongs to a set. False positive matches are possible but not common, false negatives are not possible. 7 | The Bloom filter library also implements Rabin–Karp algorithm with Rabin fingerprint hashes for multiple substring searches. 8 | 9 | This is a port of a [similar lib](https://github.com/bbondy/bloom-filter-js) I prototyped in JS. 10 | 11 | ## To include bloom-filter-cpp in your project: 12 | 13 | ``` 14 | npm install --save bloom-filter-cpp 15 | ``` 16 | 17 | 18 | ## JS Usage 19 | 20 | ```javascript 21 | var BloomFilter = require('bloom-filter-cpp').BloomFilter 22 | 23 | var b1 = new BloomFilter() 24 | 25 | console.log('b1 ading hello') 26 | b1.add('hello') 27 | 28 | console.log('b1 exists hello? ', b1.exists('hello')) 29 | console.log('b1 exists hello2? ', b1.exists('hello2')) 30 | 31 | var b2 = new BloomFilter() 32 | console.log('b2 exists hello? ', b2.exists('hello')) 33 | console.log('b2 exists hello2? ', b2.exists('hello2')) 34 | ``` 35 | 36 | 37 | ## C++ Usage 38 | 39 | ```c++ 40 | #include "BloomFilter.h" 41 | #include 42 | 43 | using namespace std; 44 | 45 | int main(int argc, char**argv) { 46 | BloomFilter b; 47 | b.add("Brian"); 48 | b.add("Ronald"); 49 | b.add("Bondy"); 50 | 51 | // Prints true 52 | cout << (b.exists("Brian") ? "true" : "false") << endl; 53 | 54 | // Prints false 55 | cout << (b.exists("Brian Ronald") ? "true" : "false") << endl; 56 | 57 | // Create a new BloomerFilter form a previous serialization 58 | BloomFilter b2(b.getBuffer(), b.getByteBufferSize()); 59 | 60 | // Prints the same as above 61 | cout << (b2.exists("Brian") ? "true" : "false") << endl; 62 | cout << (b2.exists("Brian Ronald") ? "true" : "false") << endl; 63 | 64 | // And you can check if any substring of a passed string exists 65 | // Prints true 66 | cout << (b.substringExists("Hello my name is Brian", 5) ? "true" : "false") << endl; 67 | // Prints false 68 | cout << (b.substringExists("Hello my name is Bri", 3) ? "true" : "false") << endl; 69 | 70 | return 0; 71 | } 72 | ``` 73 | 74 | 75 | ## Developing bloom-filter-cpp 76 | 77 | ```` 78 | git clone bloom-filter-cpp 79 | npm install 80 | ``` 81 | 82 | ## Build everything in release 83 | 84 | ``` 85 | make 86 | ``` 87 | 88 | ## Running sample 89 | 90 | ``` 91 | make sample 92 | ``` 93 | 94 | ## Running tests 95 | 96 | ``` 97 | make test 98 | ``` 99 | 100 | ## Clearing build files 101 | ``` 102 | make clean 103 | ``` 104 | -------------------------------------------------------------------------------- /addon.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 Brian R. Bondy. Distributed under the MPL2 license. 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 | 6 | #include 7 | #include "BloomFilterWrap.h" 8 | 9 | namespace BloomFilterWrap { 10 | 11 | using v8::Local; 12 | using v8::Object; 13 | 14 | void InitAll(Local exports) { 15 | BloomFilterWrap::Init(exports); 16 | } 17 | 18 | NODE_MODULE(addon, InitAll) 19 | 20 | } // namespace BloomFilterWrap 21 | -------------------------------------------------------------------------------- /base.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 Brian R. Bondy. Distributed under the MPL2 license. 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 | 6 | #ifndef BASE_H_ 7 | #define BASE_H_ 8 | 9 | #if !defined(nullptr) && !defined(_MSC_VER) 10 | #define nullptr 0 11 | #endif 12 | 13 | #include 14 | 15 | #endif // BASE_H_ 16 | -------------------------------------------------------------------------------- /binding.gyp: -------------------------------------------------------------------------------- 1 | { 2 | "targets": [{ 3 | "target_name": "bloom-filter-cpp", 4 | "sources": [ 5 | "addon.cpp", 6 | "BloomFilterWrap.cpp", 7 | "BloomFilterWrap.h", 8 | "BloomFilter.cpp", 9 | "BloomFilter.h", 10 | "hashFn.cpp", 11 | ], 12 | "include_dirs": [ 13 | ".", 14 | ], 15 | "conditions": [ 16 | ['OS=="win"', { 17 | }, { 18 | 'cflags_cc': [ '-fexceptions' ] 19 | } 20 | ] 21 | ], 22 | "xcode_settings": { 23 | "OTHER_CFLAGS": [ "-ObjC" ], 24 | "OTHER_CPLUSPLUSFLAGS" : ["-std=c++11","-stdlib=libc++", "-v"], 25 | "MACOSX_DEPLOYMENT_TARGET": "10.9", 26 | "GCC_ENABLE_CPP_EXCEPTIONS": "YES", 27 | }, 28 | }] 29 | } 30 | -------------------------------------------------------------------------------- /brave/BUILD.gn: -------------------------------------------------------------------------------- 1 | config("internal_config") { 2 | } 3 | 4 | config("external_config") { 5 | include_dirs = [ ".." ] 6 | } 7 | 8 | source_set("bloom-filter-cpp") { 9 | configs += [ ":internal_config" ] 10 | public_configs = [ ":external_config" ] 11 | sources = [ 12 | "../BloomFilter.cpp", 13 | "../BloomFilter.h", 14 | "../hashFn.cpp", 15 | "../hashFn.h", 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /hashFn.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 Brian R. Bondy. Distributed under the MPL2 license. 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 | 6 | #include "hashFn.h" 7 | 8 | uint64_t HashFn::operator()(const char *input, int len, 9 | unsigned char lastCharCode, uint64_t lastHash) { 10 | // See the abracadabra example: 11 | // https://en.wikipedia.org/wiki/Rabin%E2%80%93Karp_algorithm 12 | return (lastHash - lastCharCode * 13 | customPow(&precomputedPowers, precompute, p, len - 1)) * 14 | p + input[len - 1]; 15 | } 16 | 17 | uint64_t HashFn::operator()(const char *input, int len) { 18 | uint64_t total = 0; 19 | for (int i = 0; i < len; i++) { 20 | total += input[i] * 21 | customPow(&precomputedPowers, precompute, p, len - i - 1); 22 | } 23 | return total; 24 | } 25 | -------------------------------------------------------------------------------- /hashFn.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 Brian R. Bondy. Distributed under the MPL2 license. 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 | 6 | #ifndef HASHFN_H_ 7 | #define HASHFN_H_ 8 | 9 | #include "./base.h" 10 | 11 | typedef uint64_t uint64Array[30]; 12 | static int precomputedArraySize = sizeof(uint64Array) / sizeof(uint64_t); 13 | 14 | inline uint64_t customPow(uint64Array *precomputedPowers, bool usePrecomputed, 15 | uint64_t base, int exp) { 16 | if (usePrecomputed && exp < precomputedArraySize) { 17 | return (*precomputedPowers)[exp]; 18 | } 19 | 20 | // TOOD: Optimization possible here when passed in toSize which is bigger 21 | // than precomputedArraySize, we can start from the value of the last 22 | // precomputed value. 23 | uint64_t result = 1; 24 | while (exp) { 25 | if (exp & 1) 26 | result *= base; 27 | exp >>= 1; 28 | base *= base; 29 | } 30 | return result; 31 | } 32 | 33 | 34 | // Functor for a hashing function 35 | // Implements a Rabin fingerprint hash function 36 | class HashFn { 37 | public: 38 | // Initialize a HashFn with the prime p which is used as the base of the Rabin 39 | // fingerprint algorithm 40 | explicit HashFn(int p, bool precompute = true) { 41 | this->p = p; 42 | this->precompute = precompute; 43 | if (precompute) { 44 | uint64_t result = 1; 45 | for (int i = 0; i < precomputedArraySize; i++) { 46 | precomputedPowers[i] = result; 47 | result *= p; 48 | } 49 | } 50 | } 51 | 52 | virtual uint64_t operator()(const char *input, int len, 53 | unsigned char lastCharCode, uint64_t lastHash); 54 | 55 | virtual uint64_t operator()(const char *input, int len); 56 | 57 | private: 58 | int p; 59 | bool precompute; 60 | uint64Array precomputedPowers; 61 | }; 62 | 63 | #endif // HASHFN_H_ 64 | -------------------------------------------------------------------------------- /include.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | console.log(path.relative('.', __dirname),'..'); 3 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 Brian R. Bondy. Distributed under the MPL2 license. 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 | 6 | #include 7 | #include "BloomFilter.h" 8 | 9 | using std::cout; 10 | using std::endl; 11 | 12 | char separatorBuffer[32] = { 0, 0, 0, 0, 0, -128, 0, -92, 0, 0, 0, 64 }; 13 | inline bool isSeparatorChar(char c) { 14 | return !!(separatorBuffer[c / 8] & 1 << c % 8); 15 | } 16 | 17 | int main(int argc, char**argv) { 18 | BloomFilter bloomFilter(8, 32); 19 | bloomFilter.setBit(static_cast(':')); 20 | bloomFilter.setBit(static_cast('?')); 21 | bloomFilter.setBit(static_cast('/')); 22 | bloomFilter.setBit(static_cast('=')); 23 | bloomFilter.setBit(static_cast('^')); 24 | cout << "size: " << bloomFilter.getByteBufferSize() << endl; 25 | for (int i = 0; i < bloomFilter.getByteBufferSize(); i++) { 26 | cout << " " << static_cast(bloomFilter.getBuffer()[i]); 27 | } 28 | cout << endl; 29 | 30 | cout << "Separator chars: " << isSeparatorChar(':') << " " 31 | << isSeparatorChar('?') << " " << isSeparatorChar('/') << " " 32 | << isSeparatorChar('=') << isSeparatorChar('^') << endl; 33 | 34 | cout << "NON Separator chars: " << isSeparatorChar('a') << " " 35 | << isSeparatorChar('!') << " " << isSeparatorChar('#') << " " 36 | << isSeparatorChar('X') << isSeparatorChar('.') 37 | << isSeparatorChar('\\') << isSeparatorChar('"') 38 | << isSeparatorChar(-128) << endl; 39 | 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bloom-filter-cpp", 3 | "version": "1.2.2", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "abbrev": { 8 | "version": "1.1.1", 9 | "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", 10 | "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", 11 | "dev": true 12 | }, 13 | "ajv": { 14 | "version": "6.10.0", 15 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", 16 | "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", 17 | "dev": true, 18 | "requires": { 19 | "fast-deep-equal": "^2.0.1", 20 | "fast-json-stable-stringify": "^2.0.0", 21 | "json-schema-traverse": "^0.4.1", 22 | "uri-js": "^4.2.2" 23 | } 24 | }, 25 | "ansi-regex": { 26 | "version": "2.1.1", 27 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", 28 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", 29 | "dev": true 30 | }, 31 | "aproba": { 32 | "version": "1.2.0", 33 | "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", 34 | "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", 35 | "dev": true 36 | }, 37 | "are-we-there-yet": { 38 | "version": "1.1.5", 39 | "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", 40 | "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", 41 | "dev": true, 42 | "requires": { 43 | "delegates": "^1.0.0", 44 | "readable-stream": "^2.0.6" 45 | } 46 | }, 47 | "asn1": { 48 | "version": "0.2.4", 49 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", 50 | "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", 51 | "dev": true, 52 | "requires": { 53 | "safer-buffer": "~2.1.0" 54 | } 55 | }, 56 | "assert-plus": { 57 | "version": "1.0.0", 58 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 59 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", 60 | "dev": true 61 | }, 62 | "asynckit": { 63 | "version": "0.4.0", 64 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 65 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", 66 | "dev": true 67 | }, 68 | "aws-sign2": { 69 | "version": "0.7.0", 70 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", 71 | "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", 72 | "dev": true 73 | }, 74 | "aws4": { 75 | "version": "1.8.0", 76 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", 77 | "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", 78 | "dev": true 79 | }, 80 | "balanced-match": { 81 | "version": "1.0.0", 82 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 83 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 84 | "dev": true 85 | }, 86 | "bcrypt-pbkdf": { 87 | "version": "1.0.2", 88 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", 89 | "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", 90 | "dev": true, 91 | "requires": { 92 | "tweetnacl": "^0.14.3" 93 | } 94 | }, 95 | "brace-expansion": { 96 | "version": "1.1.11", 97 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 98 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 99 | "dev": true, 100 | "requires": { 101 | "balanced-match": "^1.0.0", 102 | "concat-map": "0.0.1" 103 | } 104 | }, 105 | "buffer-from": { 106 | "version": "1.1.0", 107 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.0.tgz", 108 | "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==", 109 | "dev": true 110 | }, 111 | "caseless": { 112 | "version": "0.12.0", 113 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", 114 | "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", 115 | "dev": true 116 | }, 117 | "chownr": { 118 | "version": "1.1.1", 119 | "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz", 120 | "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==", 121 | "dev": true 122 | }, 123 | "code-point-at": { 124 | "version": "1.1.0", 125 | "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", 126 | "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", 127 | "dev": true 128 | }, 129 | "combined-stream": { 130 | "version": "1.0.7", 131 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", 132 | "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", 133 | "dev": true, 134 | "requires": { 135 | "delayed-stream": "~1.0.0" 136 | } 137 | }, 138 | "concat-map": { 139 | "version": "0.0.1", 140 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 141 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 142 | "dev": true 143 | }, 144 | "concat-stream": { 145 | "version": "1.6.2", 146 | "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", 147 | "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", 148 | "dev": true, 149 | "requires": { 150 | "buffer-from": "^1.0.0", 151 | "inherits": "^2.0.3", 152 | "readable-stream": "^2.2.2", 153 | "typedarray": "^0.0.6" 154 | } 155 | }, 156 | "console-control-strings": { 157 | "version": "1.1.0", 158 | "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", 159 | "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", 160 | "dev": true 161 | }, 162 | "core-util-is": { 163 | "version": "1.0.2", 164 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 165 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", 166 | "dev": true 167 | }, 168 | "cppunitlite": { 169 | "version": "1.0.0", 170 | "resolved": "https://registry.npmjs.org/cppunitlite/-/cppunitlite-1.0.0.tgz", 171 | "integrity": "sha1-2bM71NvefeawnjU0F24EZlP6vOs=", 172 | "dev": true 173 | }, 174 | "cross-spawn": { 175 | "version": "5.1.0", 176 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", 177 | "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", 178 | "dev": true, 179 | "requires": { 180 | "lru-cache": "^4.0.1", 181 | "shebang-command": "^1.2.0", 182 | "which": "^1.2.9" 183 | } 184 | }, 185 | "dashdash": { 186 | "version": "1.14.1", 187 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", 188 | "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", 189 | "dev": true, 190 | "requires": { 191 | "assert-plus": "^1.0.0" 192 | } 193 | }, 194 | "delayed-stream": { 195 | "version": "1.0.0", 196 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 197 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", 198 | "dev": true 199 | }, 200 | "delegates": { 201 | "version": "1.0.0", 202 | "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", 203 | "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", 204 | "dev": true 205 | }, 206 | "ecc-jsbn": { 207 | "version": "0.1.2", 208 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", 209 | "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", 210 | "dev": true, 211 | "requires": { 212 | "jsbn": "~0.1.0", 213 | "safer-buffer": "^2.1.0" 214 | } 215 | }, 216 | "extend": { 217 | "version": "3.0.2", 218 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", 219 | "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", 220 | "dev": true 221 | }, 222 | "extsprintf": { 223 | "version": "1.3.0", 224 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", 225 | "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", 226 | "dev": true 227 | }, 228 | "fast-deep-equal": { 229 | "version": "2.0.1", 230 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", 231 | "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", 232 | "dev": true 233 | }, 234 | "fast-json-stable-stringify": { 235 | "version": "2.0.0", 236 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", 237 | "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", 238 | "dev": true 239 | }, 240 | "forever-agent": { 241 | "version": "0.6.1", 242 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", 243 | "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", 244 | "dev": true 245 | }, 246 | "form-data": { 247 | "version": "2.3.3", 248 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", 249 | "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", 250 | "dev": true, 251 | "requires": { 252 | "asynckit": "^0.4.0", 253 | "combined-stream": "^1.0.6", 254 | "mime-types": "^2.1.12" 255 | } 256 | }, 257 | "fs-minipass": { 258 | "version": "1.2.5", 259 | "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz", 260 | "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", 261 | "dev": true, 262 | "requires": { 263 | "minipass": "^2.2.1" 264 | } 265 | }, 266 | "fs.realpath": { 267 | "version": "1.0.0", 268 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 269 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 270 | "dev": true 271 | }, 272 | "gauge": { 273 | "version": "2.7.4", 274 | "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", 275 | "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", 276 | "dev": true, 277 | "requires": { 278 | "aproba": "^1.0.3", 279 | "console-control-strings": "^1.0.0", 280 | "has-unicode": "^2.0.0", 281 | "object-assign": "^4.1.0", 282 | "signal-exit": "^3.0.0", 283 | "string-width": "^1.0.1", 284 | "strip-ansi": "^3.0.1", 285 | "wide-align": "^1.1.0" 286 | } 287 | }, 288 | "getpass": { 289 | "version": "0.1.7", 290 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", 291 | "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", 292 | "dev": true, 293 | "requires": { 294 | "assert-plus": "^1.0.0" 295 | } 296 | }, 297 | "glob": { 298 | "version": "7.1.3", 299 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", 300 | "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", 301 | "dev": true, 302 | "requires": { 303 | "fs.realpath": "^1.0.0", 304 | "inflight": "^1.0.4", 305 | "inherits": "2", 306 | "minimatch": "^3.0.4", 307 | "once": "^1.3.0", 308 | "path-is-absolute": "^1.0.0" 309 | } 310 | }, 311 | "graceful-fs": { 312 | "version": "4.1.15", 313 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", 314 | "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", 315 | "dev": true 316 | }, 317 | "har-schema": { 318 | "version": "2.0.0", 319 | "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", 320 | "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", 321 | "dev": true 322 | }, 323 | "har-validator": { 324 | "version": "5.1.3", 325 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", 326 | "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", 327 | "dev": true, 328 | "requires": { 329 | "ajv": "^6.5.5", 330 | "har-schema": "^2.0.0" 331 | } 332 | }, 333 | "has-unicode": { 334 | "version": "2.0.1", 335 | "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", 336 | "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", 337 | "dev": true 338 | }, 339 | "http-signature": { 340 | "version": "1.2.0", 341 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", 342 | "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", 343 | "dev": true, 344 | "requires": { 345 | "assert-plus": "^1.0.0", 346 | "jsprim": "^1.2.2", 347 | "sshpk": "^1.7.0" 348 | } 349 | }, 350 | "inflight": { 351 | "version": "1.0.6", 352 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 353 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 354 | "dev": true, 355 | "requires": { 356 | "once": "^1.3.0", 357 | "wrappy": "1" 358 | } 359 | }, 360 | "inherits": { 361 | "version": "2.0.3", 362 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 363 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", 364 | "dev": true 365 | }, 366 | "is-fullwidth-code-point": { 367 | "version": "1.0.0", 368 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", 369 | "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", 370 | "dev": true, 371 | "requires": { 372 | "number-is-nan": "^1.0.0" 373 | } 374 | }, 375 | "is-typedarray": { 376 | "version": "1.0.0", 377 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", 378 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", 379 | "dev": true 380 | }, 381 | "isarray": { 382 | "version": "1.0.0", 383 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 384 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", 385 | "dev": true 386 | }, 387 | "isexe": { 388 | "version": "2.0.0", 389 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 390 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", 391 | "dev": true 392 | }, 393 | "isstream": { 394 | "version": "0.1.2", 395 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", 396 | "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", 397 | "dev": true 398 | }, 399 | "jsbn": { 400 | "version": "0.1.1", 401 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", 402 | "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", 403 | "dev": true 404 | }, 405 | "json-schema": { 406 | "version": "0.2.3", 407 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", 408 | "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", 409 | "dev": true 410 | }, 411 | "json-schema-traverse": { 412 | "version": "0.4.1", 413 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 414 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 415 | "dev": true 416 | }, 417 | "json-stringify-safe": { 418 | "version": "5.0.1", 419 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", 420 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", 421 | "dev": true 422 | }, 423 | "jsprim": { 424 | "version": "1.4.1", 425 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", 426 | "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", 427 | "dev": true, 428 | "requires": { 429 | "assert-plus": "1.0.0", 430 | "extsprintf": "1.3.0", 431 | "json-schema": "0.2.3", 432 | "verror": "1.10.0" 433 | } 434 | }, 435 | "lru-cache": { 436 | "version": "4.1.3", 437 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", 438 | "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", 439 | "dev": true, 440 | "requires": { 441 | "pseudomap": "^1.0.2", 442 | "yallist": "^2.1.2" 443 | } 444 | }, 445 | "mime-db": { 446 | "version": "1.40.0", 447 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", 448 | "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==", 449 | "dev": true 450 | }, 451 | "mime-types": { 452 | "version": "2.1.24", 453 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", 454 | "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", 455 | "dev": true, 456 | "requires": { 457 | "mime-db": "1.40.0" 458 | } 459 | }, 460 | "minimatch": { 461 | "version": "3.0.4", 462 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 463 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 464 | "dev": true, 465 | "requires": { 466 | "brace-expansion": "^1.1.7" 467 | } 468 | }, 469 | "minimist": { 470 | "version": "0.0.8", 471 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 472 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", 473 | "dev": true 474 | }, 475 | "minipass": { 476 | "version": "2.3.5", 477 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz", 478 | "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", 479 | "dev": true, 480 | "requires": { 481 | "safe-buffer": "^5.1.2", 482 | "yallist": "^3.0.0" 483 | }, 484 | "dependencies": { 485 | "yallist": { 486 | "version": "3.0.3", 487 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", 488 | "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", 489 | "dev": true 490 | } 491 | } 492 | }, 493 | "minizlib": { 494 | "version": "1.2.1", 495 | "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.2.1.tgz", 496 | "integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==", 497 | "dev": true, 498 | "requires": { 499 | "minipass": "^2.2.1" 500 | } 501 | }, 502 | "mkdirp": { 503 | "version": "0.5.1", 504 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 505 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 506 | "dev": true, 507 | "requires": { 508 | "minimist": "0.0.8" 509 | } 510 | }, 511 | "nan": { 512 | "version": "2.13.2", 513 | "resolved": "https://registry.npmjs.org/nan/-/nan-2.13.2.tgz", 514 | "integrity": "sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw==", 515 | "dev": true 516 | }, 517 | "node-gyp": { 518 | "version": "4.0.0", 519 | "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-4.0.0.tgz", 520 | "integrity": "sha512-2XiryJ8sICNo6ej8d0idXDEMKfVfFK7kekGCtJAuelGsYHQxhj13KTf95swTCN2dZ/4lTfZ84Fu31jqJEEgjWA==", 521 | "dev": true, 522 | "requires": { 523 | "glob": "^7.0.3", 524 | "graceful-fs": "^4.1.2", 525 | "mkdirp": "^0.5.0", 526 | "nopt": "2 || 3", 527 | "npmlog": "0 || 1 || 2 || 3 || 4", 528 | "osenv": "0", 529 | "request": "^2.87.0", 530 | "rimraf": "2", 531 | "semver": "~5.3.0", 532 | "tar": "^4.4.8", 533 | "which": "1" 534 | } 535 | }, 536 | "nopt": { 537 | "version": "3.0.6", 538 | "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", 539 | "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", 540 | "dev": true, 541 | "requires": { 542 | "abbrev": "1" 543 | } 544 | }, 545 | "npmlog": { 546 | "version": "4.1.2", 547 | "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", 548 | "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", 549 | "dev": true, 550 | "requires": { 551 | "are-we-there-yet": "~1.1.2", 552 | "console-control-strings": "~1.1.0", 553 | "gauge": "~2.7.3", 554 | "set-blocking": "~2.0.0" 555 | } 556 | }, 557 | "number-is-nan": { 558 | "version": "1.0.1", 559 | "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", 560 | "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", 561 | "dev": true 562 | }, 563 | "oauth-sign": { 564 | "version": "0.9.0", 565 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", 566 | "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", 567 | "dev": true 568 | }, 569 | "object-assign": { 570 | "version": "4.1.1", 571 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 572 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", 573 | "dev": true 574 | }, 575 | "once": { 576 | "version": "1.4.0", 577 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 578 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 579 | "dev": true, 580 | "requires": { 581 | "wrappy": "1" 582 | } 583 | }, 584 | "os-homedir": { 585 | "version": "1.0.2", 586 | "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", 587 | "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", 588 | "dev": true 589 | }, 590 | "os-shim": { 591 | "version": "0.1.3", 592 | "resolved": "https://registry.npmjs.org/os-shim/-/os-shim-0.1.3.tgz", 593 | "integrity": "sha1-a2LDeRz3kJ6jXtRuF2WLtBfLORc=", 594 | "dev": true 595 | }, 596 | "os-tmpdir": { 597 | "version": "1.0.2", 598 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", 599 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", 600 | "dev": true 601 | }, 602 | "osenv": { 603 | "version": "0.1.5", 604 | "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", 605 | "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", 606 | "dev": true, 607 | "requires": { 608 | "os-homedir": "^1.0.0", 609 | "os-tmpdir": "^1.0.0" 610 | } 611 | }, 612 | "path-is-absolute": { 613 | "version": "1.0.1", 614 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 615 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 616 | "dev": true 617 | }, 618 | "performance-now": { 619 | "version": "2.1.0", 620 | "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", 621 | "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", 622 | "dev": true 623 | }, 624 | "pre-commit": { 625 | "version": "1.2.2", 626 | "resolved": "https://registry.npmjs.org/pre-commit/-/pre-commit-1.2.2.tgz", 627 | "integrity": "sha1-287g7p3nI15X95xW186UZBpp7sY=", 628 | "dev": true, 629 | "requires": { 630 | "cross-spawn": "^5.0.1", 631 | "spawn-sync": "^1.0.15", 632 | "which": "1.2.x" 633 | }, 634 | "dependencies": { 635 | "which": { 636 | "version": "1.2.14", 637 | "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", 638 | "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", 639 | "dev": true, 640 | "requires": { 641 | "isexe": "^2.0.0" 642 | } 643 | } 644 | } 645 | }, 646 | "process-nextick-args": { 647 | "version": "2.0.0", 648 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", 649 | "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", 650 | "dev": true 651 | }, 652 | "pseudomap": { 653 | "version": "1.0.2", 654 | "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", 655 | "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", 656 | "dev": true 657 | }, 658 | "psl": { 659 | "version": "1.1.31", 660 | "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", 661 | "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==", 662 | "dev": true 663 | }, 664 | "punycode": { 665 | "version": "2.1.1", 666 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", 667 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", 668 | "dev": true 669 | }, 670 | "qs": { 671 | "version": "6.5.2", 672 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", 673 | "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", 674 | "dev": true 675 | }, 676 | "readable-stream": { 677 | "version": "2.3.6", 678 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", 679 | "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", 680 | "dev": true, 681 | "requires": { 682 | "core-util-is": "~1.0.0", 683 | "inherits": "~2.0.3", 684 | "isarray": "~1.0.0", 685 | "process-nextick-args": "~2.0.0", 686 | "safe-buffer": "~5.1.1", 687 | "string_decoder": "~1.1.1", 688 | "util-deprecate": "~1.0.1" 689 | } 690 | }, 691 | "request": { 692 | "version": "2.88.0", 693 | "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", 694 | "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", 695 | "dev": true, 696 | "requires": { 697 | "aws-sign2": "~0.7.0", 698 | "aws4": "^1.8.0", 699 | "caseless": "~0.12.0", 700 | "combined-stream": "~1.0.6", 701 | "extend": "~3.0.2", 702 | "forever-agent": "~0.6.1", 703 | "form-data": "~2.3.2", 704 | "har-validator": "~5.1.0", 705 | "http-signature": "~1.2.0", 706 | "is-typedarray": "~1.0.0", 707 | "isstream": "~0.1.2", 708 | "json-stringify-safe": "~5.0.1", 709 | "mime-types": "~2.1.19", 710 | "oauth-sign": "~0.9.0", 711 | "performance-now": "^2.1.0", 712 | "qs": "~6.5.2", 713 | "safe-buffer": "^5.1.2", 714 | "tough-cookie": "~2.4.3", 715 | "tunnel-agent": "^0.6.0", 716 | "uuid": "^3.3.2" 717 | } 718 | }, 719 | "rimraf": { 720 | "version": "2.6.3", 721 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", 722 | "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", 723 | "dev": true, 724 | "requires": { 725 | "glob": "^7.1.3" 726 | } 727 | }, 728 | "safe-buffer": { 729 | "version": "5.1.2", 730 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 731 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", 732 | "dev": true 733 | }, 734 | "safer-buffer": { 735 | "version": "2.1.2", 736 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 737 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", 738 | "dev": true 739 | }, 740 | "semver": { 741 | "version": "5.3.0", 742 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", 743 | "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", 744 | "dev": true 745 | }, 746 | "set-blocking": { 747 | "version": "2.0.0", 748 | "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", 749 | "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", 750 | "dev": true 751 | }, 752 | "shebang-command": { 753 | "version": "1.2.0", 754 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", 755 | "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", 756 | "dev": true, 757 | "requires": { 758 | "shebang-regex": "^1.0.0" 759 | } 760 | }, 761 | "shebang-regex": { 762 | "version": "1.0.0", 763 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", 764 | "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", 765 | "dev": true 766 | }, 767 | "signal-exit": { 768 | "version": "3.0.2", 769 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", 770 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", 771 | "dev": true 772 | }, 773 | "spawn-sync": { 774 | "version": "1.0.15", 775 | "resolved": "https://registry.npmjs.org/spawn-sync/-/spawn-sync-1.0.15.tgz", 776 | "integrity": "sha1-sAeZVX63+wyDdsKdROih6mfldHY=", 777 | "dev": true, 778 | "requires": { 779 | "concat-stream": "^1.4.7", 780 | "os-shim": "^0.1.2" 781 | } 782 | }, 783 | "sshpk": { 784 | "version": "1.16.1", 785 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", 786 | "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", 787 | "dev": true, 788 | "requires": { 789 | "asn1": "~0.2.3", 790 | "assert-plus": "^1.0.0", 791 | "bcrypt-pbkdf": "^1.0.0", 792 | "dashdash": "^1.12.0", 793 | "ecc-jsbn": "~0.1.1", 794 | "getpass": "^0.1.1", 795 | "jsbn": "~0.1.0", 796 | "safer-buffer": "^2.0.2", 797 | "tweetnacl": "~0.14.0" 798 | } 799 | }, 800 | "string-width": { 801 | "version": "1.0.2", 802 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", 803 | "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", 804 | "dev": true, 805 | "requires": { 806 | "code-point-at": "^1.0.0", 807 | "is-fullwidth-code-point": "^1.0.0", 808 | "strip-ansi": "^3.0.0" 809 | } 810 | }, 811 | "string_decoder": { 812 | "version": "1.1.1", 813 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 814 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 815 | "dev": true, 816 | "requires": { 817 | "safe-buffer": "~5.1.0" 818 | } 819 | }, 820 | "strip-ansi": { 821 | "version": "3.0.1", 822 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", 823 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", 824 | "dev": true, 825 | "requires": { 826 | "ansi-regex": "^2.0.0" 827 | } 828 | }, 829 | "tar": { 830 | "version": "4.4.8", 831 | "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.8.tgz", 832 | "integrity": "sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==", 833 | "dev": true, 834 | "requires": { 835 | "chownr": "^1.1.1", 836 | "fs-minipass": "^1.2.5", 837 | "minipass": "^2.3.4", 838 | "minizlib": "^1.1.1", 839 | "mkdirp": "^0.5.0", 840 | "safe-buffer": "^5.1.2", 841 | "yallist": "^3.0.2" 842 | }, 843 | "dependencies": { 844 | "yallist": { 845 | "version": "3.0.3", 846 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", 847 | "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", 848 | "dev": true 849 | } 850 | } 851 | }, 852 | "tough-cookie": { 853 | "version": "2.4.3", 854 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", 855 | "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", 856 | "dev": true, 857 | "requires": { 858 | "psl": "^1.1.24", 859 | "punycode": "^1.4.1" 860 | }, 861 | "dependencies": { 862 | "punycode": { 863 | "version": "1.4.1", 864 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", 865 | "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", 866 | "dev": true 867 | } 868 | } 869 | }, 870 | "tunnel-agent": { 871 | "version": "0.6.0", 872 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", 873 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", 874 | "dev": true, 875 | "requires": { 876 | "safe-buffer": "^5.0.1" 877 | } 878 | }, 879 | "tweetnacl": { 880 | "version": "0.14.5", 881 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", 882 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", 883 | "dev": true 884 | }, 885 | "typedarray": { 886 | "version": "0.0.6", 887 | "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", 888 | "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", 889 | "dev": true 890 | }, 891 | "uri-js": { 892 | "version": "4.2.2", 893 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", 894 | "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", 895 | "dev": true, 896 | "requires": { 897 | "punycode": "^2.1.0" 898 | } 899 | }, 900 | "util-deprecate": { 901 | "version": "1.0.2", 902 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 903 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", 904 | "dev": true 905 | }, 906 | "uuid": { 907 | "version": "3.3.2", 908 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", 909 | "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", 910 | "dev": true 911 | }, 912 | "verror": { 913 | "version": "1.10.0", 914 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", 915 | "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", 916 | "dev": true, 917 | "requires": { 918 | "assert-plus": "^1.0.0", 919 | "core-util-is": "1.0.2", 920 | "extsprintf": "^1.2.0" 921 | } 922 | }, 923 | "which": { 924 | "version": "1.3.1", 925 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", 926 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", 927 | "dev": true, 928 | "requires": { 929 | "isexe": "^2.0.0" 930 | } 931 | }, 932 | "wide-align": { 933 | "version": "1.1.3", 934 | "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", 935 | "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", 936 | "dev": true, 937 | "requires": { 938 | "string-width": "^1.0.2 || 2" 939 | } 940 | }, 941 | "wrappy": { 942 | "version": "1.0.2", 943 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 944 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 945 | "dev": true 946 | }, 947 | "yallist": { 948 | "version": "2.1.2", 949 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", 950 | "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", 951 | "dev": true 952 | } 953 | } 954 | } 955 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bloom-filter-cpp", 3 | "main": "./build/Release/bloom-filter-cpp", 4 | "version": "1.2.2", 5 | "description": "", 6 | "directories": { 7 | "test": "test" 8 | }, 9 | "dependencies": {}, 10 | "devDependencies": { 11 | "cppunitlite": "^1.0.0", 12 | "nan": "^2.13.2", 13 | "node-gyp": "^4.0.0", 14 | "pre-commit": "^1.2.2" 15 | }, 16 | "scripts": { 17 | "build": "make", 18 | "test": "make test", 19 | "lint": "./scripts/cpplint.py", 20 | "install": "node-gyp rebuild" 21 | }, 22 | "repository": { 23 | "type": "git", 24 | "url": "git+https://github.com/bbondy/bloom-filter-cpp.git" 25 | }, 26 | "author": "Brian R. Bondy (http://www.brianbondy.com)", 27 | "license": "MPL-2.0", 28 | "gypfile": true, 29 | "bugs": { 30 | "url": "https://github.com/bbondy/bloom-filter-cpp/issues" 31 | }, 32 | "homepage": "https://github.com/bbondy/bloom-filter-cpp#readme", 33 | "pre-commit": [ 34 | "lint" 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /sample/binding.gyp: -------------------------------------------------------------------------------- 1 | { 2 | "targets": [{ 3 | "target_name": "sample", 4 | "type": "executable", 5 | "sources": [ 6 | "../main.cpp", 7 | "../BloomFilter.cpp", 8 | "../BloomFilter.h", 9 | "../hashFn.cpp", 10 | ], 11 | "include_dirs": [ 12 | "..", 13 | ], 14 | "conditions": [ 15 | ['OS=="win"', { 16 | }, { 17 | 'cflags_cc': [ '-fexceptions' ] 18 | } 19 | ] 20 | ], 21 | "xcode_settings": { 22 | "OTHER_CFLAGS": [ "-ObjC" ], 23 | "OTHER_CPLUSPLUSFLAGS" : ["-std=c++11","-stdlib=libc++", "-v"], 24 | "OTHER_LDFLAGS": ["-stdlib=libc++"], 25 | "MACOSX_DEPLOYMENT_TARGET": "10.9", 26 | "GCC_ENABLE_CPP_EXCEPTIONS": "YES", 27 | }, 28 | }] 29 | } 30 | -------------------------------------------------------------------------------- /scripts/cpplint.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import fnmatch 4 | import os 5 | import sys 6 | 7 | from lib.util import execute 8 | 9 | IGNORE_FILES = [ 10 | # os.path.join('./node_modules', 'nan', 'nan_implementation_12_inl.h') 11 | ] 12 | 13 | SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) 14 | 15 | 16 | def main(): 17 | os.chdir(SOURCE_ROOT) 18 | files = list_files([''], 19 | ['*.cpp', '*.cc', '*.h']) 20 | 21 | node_modules_files = list_files(['node_modules'], 22 | ['*.cpp', '*.cc', '*.h']) 23 | 24 | call_cpplint(list(set(files) - set(IGNORE_FILES) - set(node_modules_files))) 25 | 26 | 27 | def list_files(directories, filters): 28 | matches = [] 29 | for directory in directories: 30 | for root, _, filenames, in os.walk(os.path.join('./', directory)): 31 | for f in filters: 32 | for filename in fnmatch.filter(filenames, f): 33 | matches.append(os.path.join(root, filename)) 34 | return matches 35 | 36 | 37 | def call_cpplint(files): 38 | cpplint = os.path.join(SOURCE_ROOT, 'vendor', 'depot_tools', 'cpplint.py') 39 | execute([sys.executable, cpplint] + files) 40 | 41 | 42 | if __name__ == '__main__': 43 | sys.exit(main()) 44 | -------------------------------------------------------------------------------- /scripts/lib/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bbondy/bloom-filter-cpp/4542d66e32fa6509b366d7a2df9644bbfe435df9/scripts/lib/__init__.py -------------------------------------------------------------------------------- /scripts/lib/config.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import errno 4 | import os 5 | import platform 6 | import sys 7 | 8 | 9 | BASE_URL = os.getenv('LIBCHROMIUMCONTENT_MIRROR') or \ 10 | 'https://s3.amazonaws.com/github-janky-artifacts/libchromiumcontent' 11 | LIBCHROMIUMCONTENT_COMMIT = 'cfbe8ec7e14af4cabd1474386f54e197db1f7ac1' 12 | 13 | PLATFORM = { 14 | 'cygwin': 'win32', 15 | 'darwin': 'darwin', 16 | 'linux2': 'linux', 17 | 'win32': 'win32', 18 | }[sys.platform] 19 | 20 | verbose_mode = False 21 | 22 | 23 | def get_platform_key(): 24 | if os.environ.has_key('MAS_BUILD'): 25 | return 'mas' 26 | else: 27 | return PLATFORM 28 | 29 | 30 | def get_target_arch(): 31 | try: 32 | target_arch_path = os.path.join(__file__, '..', '..', '..', 'vendor', 33 | 'brightray', 'vendor', 'download', 34 | 'libchromiumcontent', '.target_arch') 35 | with open(os.path.normpath(target_arch_path)) as f: 36 | return f.read().strip() 37 | except IOError as e: 38 | if e.errno != errno.ENOENT: 39 | raise 40 | 41 | if PLATFORM == 'win32': 42 | return 'ia32' 43 | else: 44 | return 'x64' 45 | 46 | 47 | def get_chromedriver_version(): 48 | return 'v2.15' 49 | 50 | 51 | def s3_config(): 52 | config = (os.environ.get('ATOM_SHELL_S3_BUCKET', ''), 53 | os.environ.get('ATOM_SHELL_S3_ACCESS_KEY', ''), 54 | os.environ.get('ATOM_SHELL_S3_SECRET_KEY', '')) 55 | message = ('Error: Please set the $ATOM_SHELL_S3_BUCKET, ' 56 | '$ATOM_SHELL_S3_ACCESS_KEY, and ' 57 | '$ATOM_SHELL_S3_SECRET_KEY environment variables') 58 | assert all(len(c) for c in config), message 59 | return config 60 | 61 | 62 | def enable_verbose_mode(): 63 | print 'Running in verbose mode' 64 | global verbose_mode 65 | verbose_mode = True 66 | 67 | 68 | def is_verbose_mode(): 69 | return verbose_mode 70 | -------------------------------------------------------------------------------- /scripts/lib/github.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import json 4 | import os 5 | import re 6 | import sys 7 | 8 | REQUESTS_DIR = os.path.abspath(os.path.join(__file__, '..', '..', '..', 9 | 'vendor', 'requests')) 10 | sys.path.append(os.path.join(REQUESTS_DIR, 'build', 'lib')) 11 | sys.path.append(os.path.join(REQUESTS_DIR, 'build', 'lib.linux-x86_64-2.7')) 12 | import requests 13 | 14 | GITHUB_URL = 'https://api.github.com' 15 | GITHUB_UPLOAD_ASSET_URL = 'https://uploads.github.com' 16 | 17 | class GitHub: 18 | def __init__(self, access_token): 19 | self._authorization = 'token %s' % access_token 20 | 21 | pattern = '^/repos/{0}/{0}/releases/{1}/assets$'.format('[^/]+', '[0-9]+') 22 | self._releases_upload_api_pattern = re.compile(pattern) 23 | 24 | def __getattr__(self, attr): 25 | return _Callable(self, '/%s' % attr) 26 | 27 | def send(self, method, path, **kw): 28 | if not 'headers' in kw: 29 | kw['headers'] = dict() 30 | headers = kw['headers'] 31 | headers['Authorization'] = self._authorization 32 | headers['Accept'] = 'application/vnd.github.manifold-preview' 33 | 34 | # Switch to a different domain for the releases uploading API. 35 | if self._releases_upload_api_pattern.match(path): 36 | url = '%s%s' % (GITHUB_UPLOAD_ASSET_URL, path) 37 | else: 38 | url = '%s%s' % (GITHUB_URL, path) 39 | # Data are sent in JSON format. 40 | if 'data' in kw: 41 | kw['data'] = json.dumps(kw['data']) 42 | 43 | r = getattr(requests, method)(url, **kw).json() 44 | if 'message' in r: 45 | raise Exception(json.dumps(r, indent=2, separators=(',', ': '))) 46 | return r 47 | 48 | 49 | class _Executable: 50 | def __init__(self, gh, method, path): 51 | self._gh = gh 52 | self._method = method 53 | self._path = path 54 | 55 | def __call__(self, **kw): 56 | return self._gh.send(self._method, self._path, **kw) 57 | 58 | 59 | class _Callable(object): 60 | def __init__(self, gh, name): 61 | self._gh = gh 62 | self._name = name 63 | 64 | def __call__(self, *args): 65 | if len(args) == 0: 66 | return self 67 | 68 | name = '%s/%s' % (self._name, '/'.join([str(arg) for arg in args])) 69 | return _Callable(self._gh, name) 70 | 71 | def __getattr__(self, attr): 72 | if attr in ['get', 'put', 'post', 'patch', 'delete']: 73 | return _Executable(self._gh, attr, self._name) 74 | 75 | name = '%s/%s' % (self._name, attr) 76 | return _Callable(self._gh, name) 77 | -------------------------------------------------------------------------------- /scripts/lib/util.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import atexit 4 | import contextlib 5 | import errno 6 | import platform 7 | import re 8 | import shutil 9 | import ssl 10 | import subprocess 11 | import sys 12 | import tarfile 13 | import tempfile 14 | import urllib2 15 | import os 16 | import zipfile 17 | 18 | from config import is_verbose_mode 19 | 20 | 21 | def get_host_arch(): 22 | """Returns the host architecture with a predictable string.""" 23 | host_arch = platform.machine() 24 | 25 | # Convert machine type to format recognized by gyp. 26 | if re.match(r'i.86', host_arch) or host_arch == 'i86pc': 27 | host_arch = 'ia32' 28 | elif host_arch in ['x86_64', 'amd64']: 29 | host_arch = 'x64' 30 | elif host_arch.startswith('arm'): 31 | host_arch = 'arm' 32 | 33 | # platform.machine is based on running kernel. It's possible to use 64-bit 34 | # kernel with 32-bit userland, e.g. to give linker slightly more memory. 35 | # Distinguish between different userland bitness by querying 36 | # the python binary. 37 | if host_arch == 'x64' and platform.architecture()[0] == '32bit': 38 | host_arch = 'ia32' 39 | 40 | return host_arch 41 | 42 | 43 | def tempdir(prefix=''): 44 | directory = tempfile.mkdtemp(prefix=prefix) 45 | atexit.register(shutil.rmtree, directory) 46 | return directory 47 | 48 | 49 | @contextlib.contextmanager 50 | def scoped_cwd(path): 51 | cwd = os.getcwd() 52 | os.chdir(path) 53 | try: 54 | yield 55 | finally: 56 | os.chdir(cwd) 57 | 58 | 59 | @contextlib.contextmanager 60 | def scoped_env(key, value): 61 | origin = '' 62 | if key in os.environ: 63 | origin = os.environ[key] 64 | os.environ[key] = value 65 | try: 66 | yield 67 | finally: 68 | os.environ[key] = origin 69 | 70 | 71 | def download(text, url, path): 72 | safe_mkdir(os.path.dirname(path)) 73 | with open(path, 'wb') as local_file: 74 | if hasattr(ssl, '_create_unverified_context'): 75 | ssl._create_default_https_context = ssl._create_unverified_context 76 | 77 | web_file = urllib2.urlopen(url) 78 | file_size = int(web_file.info().getheaders("Content-Length")[0]) 79 | downloaded_size = 0 80 | block_size = 128 81 | 82 | ci = os.environ.get('CI') == '1' 83 | 84 | while True: 85 | buf = web_file.read(block_size) 86 | if not buf: 87 | break 88 | 89 | downloaded_size += len(buf) 90 | local_file.write(buf) 91 | 92 | if not ci: 93 | percent = downloaded_size * 100. / file_size 94 | status = "\r%s %10d [%3.1f%%]" % (text, downloaded_size, percent) 95 | print status, 96 | 97 | if ci: 98 | print "%s done." % (text) 99 | else: 100 | print 101 | return path 102 | 103 | 104 | def extract_tarball(tarball_path, member, destination): 105 | with tarfile.open(tarball_path) as tarball: 106 | tarball.extract(member, destination) 107 | 108 | 109 | def extract_zip(zip_path, destination): 110 | if sys.platform == 'darwin': 111 | # Use unzip command on Mac to keep symbol links in zip file work. 112 | execute(['unzip', zip_path, '-d', destination]) 113 | else: 114 | with zipfile.ZipFile(zip_path) as z: 115 | z.extractall(destination) 116 | 117 | def make_zip(zip_file_path, files, dirs): 118 | safe_unlink(zip_file_path) 119 | if sys.platform == 'darwin': 120 | files += dirs 121 | execute(['zip', '-r', '-y', zip_file_path] + files) 122 | else: 123 | zip_file = zipfile.ZipFile(zip_file_path, "w", zipfile.ZIP_DEFLATED) 124 | for filename in files: 125 | zip_file.write(filename, filename) 126 | for dirname in dirs: 127 | for root, _, filenames in os.walk(dirname): 128 | for f in filenames: 129 | zip_file.write(os.path.join(root, f)) 130 | zip_file.close() 131 | 132 | 133 | def rm_rf(path): 134 | try: 135 | shutil.rmtree(path) 136 | except OSError: 137 | pass 138 | 139 | 140 | def safe_unlink(path): 141 | try: 142 | os.unlink(path) 143 | except OSError as e: 144 | if e.errno != errno.ENOENT: 145 | raise 146 | 147 | 148 | def safe_mkdir(path): 149 | try: 150 | os.makedirs(path) 151 | except OSError as e: 152 | if e.errno != errno.EEXIST: 153 | raise 154 | 155 | 156 | def execute(argv, env=os.environ): 157 | if is_verbose_mode(): 158 | print ' '.join(argv) 159 | try: 160 | output = subprocess.check_output(argv, stderr=subprocess.STDOUT, env=env) 161 | if is_verbose_mode(): 162 | print output 163 | return output 164 | except subprocess.CalledProcessError as e: 165 | print e.output 166 | raise e 167 | 168 | 169 | def execute_stdout(argv, env=os.environ): 170 | if is_verbose_mode(): 171 | print ' '.join(argv) 172 | try: 173 | subprocess.check_call(argv, env=env) 174 | except subprocess.CalledProcessError as e: 175 | print e.output 176 | raise e 177 | else: 178 | execute(argv, env) 179 | 180 | 181 | def atom_gyp(): 182 | SOURCE_ROOT = os.path.abspath(os.path.join(__file__, '..', '..', '..')) 183 | gyp = os.path.join(SOURCE_ROOT, 'atom.gyp') 184 | with open(gyp) as f: 185 | obj = eval(f.read()); 186 | return obj['variables'] 187 | 188 | 189 | def get_atom_shell_version(): 190 | return 'v' + atom_gyp()['version%'] 191 | 192 | 193 | def parse_version(version): 194 | if version[0] == 'v': 195 | version = version[1:] 196 | 197 | vs = version.split('.') 198 | if len(vs) > 4: 199 | return vs[0:4] 200 | else: 201 | return vs + ['0'] * (4 - len(vs)) 202 | 203 | 204 | def s3put(bucket, access_key, secret_key, prefix, key_prefix, files): 205 | env = os.environ.copy() 206 | BOTO_DIR = os.path.abspath(os.path.join(__file__, '..', '..', '..', 'vendor', 207 | 'boto')) 208 | env['PYTHONPATH'] = os.path.pathsep.join([ 209 | env.get('PYTHONPATH', ''), 210 | os.path.join(BOTO_DIR, 'build', 'lib'), 211 | os.path.join(BOTO_DIR, 'build', 'lib.linux-x86_64-2.7')]) 212 | 213 | boto = os.path.join(BOTO_DIR, 'bin', 's3put') 214 | args = [ 215 | sys.executable, 216 | boto, 217 | '--bucket', bucket, 218 | '--access_key', access_key, 219 | '--secret_key', secret_key, 220 | '--prefix', prefix, 221 | '--key_prefix', key_prefix, 222 | '--grant', 'public-read' 223 | ] + files 224 | 225 | execute(args, env) 226 | -------------------------------------------------------------------------------- /test/binding.gyp: -------------------------------------------------------------------------------- 1 | { 2 | "targets": [{ 3 | "target_name": "test", 4 | "type": "executable", 5 | "sources": [ 6 | "../test/test-main.cpp", 7 | "../test/test-bloom.cpp", 8 | "../test/util.cpp", 9 | "../BloomFilter.cpp", 10 | "../hashFn.cpp", 11 | ], 12 | "include_dirs": [ 13 | "..", 14 | '../node_modules/cppunitlite', 15 | '../node_modules/nan', 16 | ], 17 | "dependencies": [ 18 | "../node_modules/cppunitlite/binding.gyp:CppUnitLite", 19 | ], 20 | "conditions": [ 21 | ['OS=="win"', { 22 | }, { 23 | 'cflags_cc': [ '-fexceptions' ] 24 | } 25 | ] 26 | ], 27 | "xcode_settings": { 28 | "OTHER_CFLAGS": [ "-ObjC" ], 29 | "OTHER_CPLUSPLUSFLAGS" : ["-std=c++11","-stdlib=libc++", "-v"], 30 | "OTHER_LDFLAGS": ["-stdlib=libc++"], 31 | "MACOSX_DEPLOYMENT_TARGET": "10.9", 32 | "GCC_ENABLE_CPP_EXCEPTIONS": "YES", 33 | }, 34 | }] 35 | } 36 | 37 | -------------------------------------------------------------------------------- /test/test-bloom.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 Brian R. Bondy. Distributed under the MPL2 license. 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include "./CppUnitLite/TestHarness.h" 15 | #include "./CppUnitLite/Test.h" 16 | #include "./BloomFilter.h" 17 | #include "./util.h" 18 | 19 | TEST(BloomFilter, isBitSetSetBit) { 20 | BloomFilter b(10, 3); 21 | 22 | // First bit in a byte 23 | CHECK(!b.isBitSet(0)) 24 | b.setBit(0); 25 | CHECK(b.isBitSet(0)) 26 | 27 | // Last bit in a byte 28 | CHECK(!b.isBitSet(7)) 29 | b.setBit(7); 30 | CHECK(b.isBitSet(7)) 31 | for (int i = 1; i <= 6; i++) { 32 | CHECK(!b.isBitSet(i)); 33 | } 34 | CHECK(b.isBitSet(0)); 35 | 36 | // Second bit in non first byte 37 | CHECK(!b.isBitSet(9)) 38 | b.setBit(9); 39 | CHECK(b.isBitSet(9)) 40 | CHECK(!b.isBitSet(1)); 41 | } 42 | 43 | // Generates a simple hash function for the specified prime 44 | TEST(BloomFilter, SimpleHashFn) { 45 | HashFn h(2); 46 | uint64_t hash = h("hi", 2); 47 | CHECK(hash == (static_cast('h')) * pow(2, 1) + 48 | static_cast('i') * pow(2, 0)); 49 | 50 | { 51 | HashFn h(19, false); 52 | HashFn h2(19, true); 53 | const char *sz = "facebook.com"; 54 | const char *sz2 = "abcde"; 55 | LONGS_EQUAL(h(sz, strlen(sz)), 12510474367240317); 56 | LONGS_EQUAL(h2(sz, strlen(sz)), 12510474367240317); 57 | LONGS_EQUAL(h(sz2, strlen(sz2)), 13351059); 58 | LONGS_EQUAL(h2(sz2, strlen(sz2)), 13351059); 59 | } 60 | } 61 | 62 | // Detects when elements are in the set and not in the set 63 | TEST(BloomFilter, Basic) { 64 | BloomFilter b; 65 | b.add("Brian"); 66 | b.add("Ronald"); 67 | b.add("Bondy"); 68 | CHECK(b.exists("Brian")); 69 | CHECK(!b.exists("Brian2")); 70 | CHECK(!b.exists("Bria")); 71 | 72 | CHECK(b.exists("Ronald")); 73 | CHECK(!b.exists("Ronald2")); 74 | CHECK(!b.exists("onald2")); 75 | 76 | CHECK(b.exists("Bondy")); 77 | CHECK(!b.exists("BrianRonaldBondy")); 78 | CHECK(!b.exists("RonaldBondy")); 79 | } 80 | 81 | void genRandomBuffer(char *s, const int len) { 82 | for (int i = 0; i < len; ++i) { 83 | s[i] = rand() % 256; // NOLINT 84 | } 85 | s[len - 1] = 0; 86 | } 87 | 88 | // Can handle long strings 89 | TEST(BloomFilter, BasicLongStrings) { 90 | const int kBufSize = 20000; 91 | char id1[kBufSize]; 92 | char id2[kBufSize]; 93 | char id3[kBufSize]; 94 | genRandomBuffer(id1, kBufSize); 95 | genRandomBuffer(id2, kBufSize); 96 | genRandomBuffer(id3, kBufSize); 97 | 98 | HashFn h1 = HashFn(0); 99 | HashFn h2 = HashFn(1023); 100 | HashFn hashFns[2] = {h1, h2}; 101 | 102 | BloomFilter b(10, 5000, hashFns, sizeof(hashFns)/sizeof(hashFns[0])); 103 | 104 | b.add(id1, kBufSize); 105 | b.add(id2, kBufSize); 106 | CHECK(b.exists(id1, kBufSize)); 107 | CHECK(b.exists(id2, kBufSize)); 108 | CHECK(!b.exists("hello")); 109 | CHECK(!b.exists(id3, kBufSize)); 110 | } 111 | 112 | // supports substringExists 113 | TEST(BloomFilter, substringExists) { 114 | BloomFilter b; 115 | b.add("abc"); 116 | b.add("hello"); 117 | b.add("world"); 118 | CHECK(b.substringExists("hello", 5)); 119 | // Only substrings of length 5 should exist in the bloom filter 120 | CHECK(!b.substringExists("ell", 3)); 121 | CHECK(b.substringExists("wow ok hello!!!!", 5)); 122 | CHECK(!b.substringExists("he!lloworl!d", 5)); 123 | } 124 | 125 | // Can return false positives for a saturated set 126 | TEST(BloomFilter, falsePositives) { 127 | BloomFilter b(2, 2); 128 | char sz[64]; 129 | for (int i = 0; i < 100; i++) { 130 | snprintf(sz, sizeof(sz), "test-%i", i); 131 | b.add(sz); 132 | } 133 | CHECK(b.exists("test")); 134 | } 135 | 136 | // It cannot return false negatives 137 | TEST(BloomFilter, noFalseNegatives) { 138 | BloomFilter b; 139 | char sz[64]; 140 | for (int i = 0; i < 100000; i++) { 141 | snprintf(sz, sizeof(sz), "test-%i", i); 142 | b.add(sz); 143 | } 144 | for (int i = 0; i < 100000; i++) { 145 | snprintf(sz, sizeof(sz), "test-%i", i); 146 | CHECK(b.exists(sz)); 147 | } 148 | } 149 | 150 | // Works with some live examples 151 | TEST(BloomFilter, liveExamples) { 152 | BloomFilter b; 153 | b.add("googlesy"); 154 | const char *url1 = 155 | "http://tpc.googlesyndication.com/safeframe/1-0-2/html/container.html#" 156 | "xpc=sf-gdn-exp-2&p=http%3A//slashdot.org"; 157 | const char *url2 = 158 | "https://tpc.googlesyndication.com/pagead/gadgets/suggestion_autolayout_V2/" 159 | "suggestion_autolayout_V2.html#t=15174732506449260991&p=http%3A%2F%2F" 160 | "tpc.googlesyndication.com"; 161 | CHECK(b.substringExists("googlesy", 8)); 162 | CHECK(b.substringExists(url1, 8)); 163 | CHECK(b.substringExists(url2, 8)); 164 | } 165 | 166 | // Works by transfering a buffer 167 | TEST(BloomFilter, transferingBuffer) { 168 | BloomFilter b; 169 | b.add("Brian"); 170 | b.add("Ronald"); 171 | b.add("Bondy"); 172 | 173 | BloomFilter b2(b.getBuffer(), b.getByteBufferSize()); 174 | CHECK(b2.exists("Brian")); 175 | CHECK(!b2.exists("Brian2")); 176 | CHECK(!b2.exists("Bria")); 177 | 178 | CHECK(b2.exists("Ronald")); 179 | CHECK(!b2.exists("Ronald2")); 180 | CHECK(!b2.exists("onald2")); 181 | 182 | CHECK(b2.exists("Bondy")); 183 | CHECK(!b2.exists("BrianRonaldBondy")); 184 | CHECK(!b2.exists("RonaldBondy")); 185 | } 186 | 187 | // Works by transfering a buffer 188 | TEST(BloomFilter, clearBloomFilter) { 189 | BloomFilter b; 190 | b.add("Brian"); 191 | CHECK(b.exists("Brian")); 192 | b.clear(); 193 | CHECK(!b.exists("Brian")); 194 | } 195 | -------------------------------------------------------------------------------- /test/test-main.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 Brian R. Bondy. Distributed under the MPL2 license. 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 | 6 | #include 7 | #include "./CppUnitLite/TestHarness.h" 8 | #include "./util.h" 9 | #include "./testResult2.h" 10 | 11 | SimpleString StringFrom(const std::string& value) { 12 | return SimpleString(value.c_str()); 13 | } 14 | 15 | int main() { 16 | TestResult2 tr; 17 | TestRegistry::runAllTests(tr); 18 | return tr.hasFailures ? 1 : 0; 19 | } 20 | -------------------------------------------------------------------------------- /test/testResult2.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 Brian R. Bondy. Distributed under the MPL2 license. 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 | 6 | #ifndef TEST_TESTRESULT2_H_ 7 | #define TEST_TESTRESULT2_H_ 8 | 9 | #include "./CppUnitLite/TestHarness.h" 10 | 11 | class TestResult2 : public TestResult { 12 | public: 13 | TestResult2() : hasFailures(false) { 14 | } 15 | virtual void addFailure(const Failure& failure) { 16 | hasFailures = true; 17 | TestResult::addFailure(failure); 18 | } 19 | bool hasFailures; 20 | }; 21 | 22 | #endif // TEST_TESTRESULT2_H_ 23 | -------------------------------------------------------------------------------- /test/util.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 Brian R. Bondy. Distributed under the MPL2 license. 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 | 6 | #include 7 | #include "CppUnitLite/TestHarness.h" 8 | #include "./util.h" 9 | -------------------------------------------------------------------------------- /test/util.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 Brian R. Bondy. Distributed under the MPL2 license. 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 | 6 | #ifndef TEST_UTIL_H_ 7 | #define TEST_UTIL_H_ 8 | 9 | #include 10 | 11 | SimpleString StringFrom(const std::string& value); 12 | 13 | #endif // TEST_UTIL_H_ 14 | --------------------------------------------------------------------------------