diff --git a/bloomrun.js b/bloomrun.js index be3aa03..64393cc 100644 --- a/bloomrun.js +++ b/bloomrun.js @@ -3,10 +3,7 @@ var Bucket = require('./lib/bucket') var Iterator = require('./lib/iterator') var PatternSet = require('./lib/patternSet') -var genKeys = require('./lib/genKeys') var matchingBuckets = require('./lib/matchingBuckets') -var deepMatch = require('./lib/deepMatch') -var deepSort = require('./lib/deepSort') var onlyRegex = require('./lib/onlyRegex') function BloomRun (opts) { @@ -16,55 +13,17 @@ function BloomRun (opts) { this._isDeep = opts && opts.indexing === 'depth' this._buckets = [] - this._regexBucket = {data: []} + this._regexBucket = new Bucket(this._isDeep) this._defaultResult = null } -function addPatterns (toAdd) { - this.filter.add(toAdd) -} - -function addPatternSet (patternSet) { - this.add(patternSet.pattern, patternSet.payload) -} - -function removePattern (bucket, pattern, payload) { - var foundPattern = false - - for (var i = 0; i < bucket.data.length; i++) { - if (deepMatch(pattern, bucket.data[i].pattern)) { - if (payload === null || payload === bucket.data[i].payload) { - bucket.data.splice(i, 1) - foundPattern = true - - removePattern(bucket, pattern, payload) - } - } - } - - return foundPattern -} - -function removeBucket (buckets, bucket) { - for (var i = 0; i < buckets.length; i++) { - if (bucket === buckets[i]) { - buckets.splice(i, 1) - } - } -} - BloomRun.prototype.default = function (payload) { this._defaultResult = payload } BloomRun.prototype.add = function (pattern, payload) { if (onlyRegex(pattern)) { - this._regexBucket.data.push(new PatternSet(pattern, payload, this._isDeep)) - - if (this._isDeep) { - this._regexBucket.data.sort(deepSort) - } - + this._regexBucket.add(new PatternSet(pattern, payload, this._isDeep)) return this } @@ -74,22 +33,28 @@ BloomRun.prototype.add = function (pattern, payload) { if (buckets.length > 0) { bucket = buckets[0] } else { - bucket = new Bucket() + bucket = new Bucket(this._isDeep) this._buckets.push(bucket) } - genKeys(pattern).forEach(addPatterns, bucket) - var patternSet = new PatternSet(pattern, payload, this._isDeep) - bucket.data.push(patternSet) - - if (this._isDeep) { - bucket.data.sort(deepSort) - } + bucket.add(patternSet) return this } +function addPatternSet (patternSet) { + this.add(patternSet.pattern, patternSet.payload) +} + +function removeBucket (buckets, bucket) { + for (var i = 0; i < buckets.length; i++) { + if (bucket === buckets[i]) { + buckets.splice(i, 1) + } + } +} + BloomRun.prototype.remove = function (pattern, payload) { var matches = matchingBuckets(this._buckets, pattern) payload = payload || null @@ -98,9 +63,9 @@ BloomRun.prototype.remove = function (pattern, payload) { for (var i = 0; i < matches.length; i++) { var bucket = matches[i] - if (removePattern(bucket, pattern, payload)) { + if (bucket.remove(pattern, payload)) { removeBucket(this._buckets, bucket) - bucket.data.forEach(addPatternSet, this) + bucket.forEach(addPatternSet, this) } } } diff --git a/lib/bucket.js b/lib/bucket.js index 09a62ea..f47e9ff 100644 --- a/lib/bucket.js +++ b/lib/bucket.js @@ -1,13 +1,55 @@ 'use strict' var BloomFilter = require('bloomfilter').BloomFilter +var deepSort = require('./deepSort') +var genKeys = require('./genKeys') +var deepMatch = require('./deepMatch') -function Bucket () { +function Bucket (isDeep) { this.filter = new BloomFilter( 32 * 256, // number of bits to allocate. 16 // number of hash functions. ) this.data = [] + this.isDeep = isDeep +} + +Bucket.prototype.add = function (set) { + genKeys(set.pattern).forEach(addPatterns, this) + this.data.push(set) + if (this.isDeep) { + this.data.sort(deepSort) + } + return this +} + +function addPatterns (toAdd) { + this.filter.add(toAdd) +} + +Bucket.prototype.remove = function (pattern, payload) { + var foundPattern = false + var data = this.data + + for (var i = 0; i < data.length; i++) { + if (deepMatch(pattern, data[i].pattern)) { + if (payload === null || payload === data[i].payload) { + data.splice(i, 1) + foundPattern = true + + // to remove all occurences + this.remove(pattern, payload) + break + } + } + } + + return foundPattern +} + +Bucket.prototype.forEach = function (func, that) { + this.data.forEach(func, that) + return this } module.exports = Bucket