UNPKG

3.38 kBJavaScriptView Raw
1'use strict';
2var Promise = require('bluebird');
3var utils = require('./utils');
4var MemStore = require('./memmap');
5var uuid = require('node-uuid');
6var insert = require('./insert');
7var remove = require('./remove');
8var append = require('./append');
9var bulk = require('./bulk');
10var query = require('./query');
11var extend = require('xtend');
12var queryStream = require('./queryStream');
13var Batches = require('./batches');
14
15module.exports = RTree;
16function promisify(store) {
17 var out = {};
18 ['get', 'put', 'del', 'batch'].forEach(function (key) {
19 out[key] = Promise.promisify(store[key], store);
20 });
21 return out;
22}
23function RTree(store, opts) {
24 opts = extend({
25 MIN: 3,
26 MAX: 9
27 }, opts);
28 this.MAX = opts.MAX;
29 this.MIN = opts.MIN;
30 this.store = promisify(store || new MemStore());
31 this.root = false;
32 this.queue = [];
33 this.inProgress = false;
34}
35RTree.prototype.insert = function (id, bbox, cb) {
36 return this.taskQueue(insert, this, id, bbox, false, false).nodeify(cb);
37};
38RTree.prototype.append = function (id, bbox, cb) {
39 return this.taskQueue(append, this, id, bbox, false, false).nodeify(cb);
40};
41RTree.prototype.remove = function (id, bbox, cb) {
42 if (!Array.isArray(bbox)) {
43 cb = bbox;
44 bbox = void 0;
45 }
46 return this.taskQueue(remove, this, id, bbox, false).nodeify(cb);
47};
48RTree.prototype.bulk = function (array, cb) {
49 return this.taskQueue(bulk, this, array).nodeify(cb);
50};
51RTree.prototype.query = function (bbox, cb) {
52 if (cb) {
53 return query(this, bbox).nodeify(cb);
54 }
55 return queryStream(this, bbox);
56};
57RTree.prototype.taskQueue = function (func) {
58 var args = new Array(arguments.length -1);
59 var len = arguments.length;
60 var i = 0;
61 while (++i < len) {
62 args[i - 1] = arguments[i];
63 }
64 var self = this;
65 function after(resp) {
66 if (self.queue.length) {
67 self.flushQueue();
68 } else {
69 self.inProgress = false;
70 }
71 }
72 if (!this.inProgress) {
73 this.inProgress = true;
74 var res = func.apply(undefined, args);
75 res.then(after);
76 return res;
77 } else {
78 return new Promise (function (fulfill, reject) {
79 self.queue.push({
80 error: reject,
81 fulfill: fulfill,
82 args: args,
83 func: func
84 });
85 });
86 }
87};
88RTree.prototype.flushQueue = function () {
89 var self = this;
90 if (!this.queue.length) {
91 self.inProgress = false;
92 return;
93 }
94 if (this.queue.length === 1) {
95 var item = this.queue.pop();
96 var res = item.func.apply(undefined, item.args);
97 item.fulfill(res);
98 res.then(function () {
99 if (self.queue.length) {
100 self.flushQueue();
101 } else {
102 self.inProgress = false;
103 }
104 });
105 return;
106 }
107 var store = new Batches(self.store);
108 var promise = Promise.resolve(true);
109 var fullfill;
110 var done = new Promise(function (f) {
111 fullfill = f;
112 });
113 var i = 0;
114 this.queue.forEach(function (item){
115 item.args.push(store);
116 promise = promise.then(function () {
117 var result = item.func.apply(undefined, item.args);
118 item.fulfill(done.then(function () {
119 return result;
120 }));
121 return result.catch(function () {
122 //we don't need errors holding up the batch
123 });
124 });
125
126 });
127 this.queue = [];
128 promise.then(function () {
129 return store.save();
130 }).then(function (resp) {
131 fullfill(resp);
132 self.flushQueue();
133 });
134};
135