2
* Copyright 2009 Google Inc.
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
* you may not use this file except in compliance with the License.
6
* You may obtain a copy of the License at
8
* http://www.apache.org/licenses/LICENSE-2.0
10
* Unless required by applicable law or agreed to in writing, software
11
* distributed under the License is distributed on an "AS-IS" BASIS,
12
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
* See the License for the specific language governing permissions and
14
* limitations under the License.
18
function makeBBTree(transferContents, augment) {
24
augment = (augment || (function(n) {}));
27
if (t != nil && t[0].level == t.level) {
40
if (t != nil && t[1][1].level == t.level) {
53
function reaugment(n) {
54
if (n != nil) augment(n);
59
self.insert = function(compare) {
85
self.remove = function(compare) {
88
var deletedEqual = false;
98
// whether the node called "deleted" is actually a
100
deletedEqual = (cmp == 0);
101
t[1] = recurse(t[1]);
103
if (t == last && deleted != nil && deletedEqual) {
104
// t may be same node as deleted
105
transferContents(t, deleted);
112
if (t[0].level < t.level-1 ||
113
t[1].level < t.level-1) {
115
if (t[1].level > t.level)
116
t[1].level = t.level;
119
t[1][1] = skew(t[1][1]);
127
root = recurse(root);
130
self.find = function(compare) {
131
function recurse(t) {
132
if (t == nil) return t;
133
var cmp = compare(t);
135
return recurse(t[0]);
138
return recurse(t[1]);
144
var result = recurse(root);
145
return (result != nil && result) || null;
148
self.root = function() { return root; }
150
self.forEach = function(func) {
151
function recurse(t) {
164
function makeBBList() {
168
function _treeSize(n) { return n.size || 0; }
169
function _treeWidth(n) { return n.width || 0; }
170
function _width(n) { return (n && n.entry && n.entry.width) || 0; }
172
function _transferContents(a, b) {
176
function _augment(n) {
177
n.size = _treeSize(n[0]) + _treeSize(n[1]) + 1;
178
n.width = _treeWidth(n[0]) + _treeWidth(n[1]) + _width(n);
183
var bb = makeBBTree(transferContents, augment);
185
function makeIndexComparator(indexFunc) {
186
var curIndex = _treeSize(bb.root()[0]);
187
return function (n) {
188
var dir = indexFunc(curIndex, n);
190
curIndex -= _treeSize(n[0][1]) + 1;
193
curIndex += _treeSize(n[1][0]) + 1;
199
function makeWidthComparator(widthFunc) {
200
var curIndex = _treeWidth(bb.root()[0]);
201
return function (n) {
202
var dir = indexFunc(curIndex, n);
204
curIndex -= _treeWidth(n[0][1]) + _width(n[0]);
207
curIndex += _treeWidth(n[1][0]) + _width(n);
213
function numcomp(a,b) { if (a < b) return -1; if (a > b) return 1; return 0; }
215
function removeByIndex(idx) {
217
bb.remove(makeComparator(function (curIndex, n) {
218
var cmp = numcomp(idx, curIndex);
219
if (cmp == 0) entry = n.entry;
225
function insertAtIndex(idx, entry) {
226
var newNode = bb.insert(makeComparator(function (curIndex) {
227
if (idx <= curIndex) return -1;
230
newNode.entry = entry;
234
var entriesByKey = {};
237
splice: function (start, deleteCount, newEntryArray) {
238
for(var i=0;i<deleteCount;i++) {
239
var oldEntry = removeByIndex(start);
241
totalWidth -= (entry.width || 0);
242
delete entriesByKey[oldEntry.key];
244
for(var i=0;i<newEntryArray.length;i++) {
245
var entry = newEntryArray[i];
246
var newNode = insertAtIndex(start+i, entry);
248
totalWidth += (entry.width || 0);
249
entriesByKey[entry.key] = entry;
252
next: function (entry) {
264
var a = makeBBTree(function (a,b) {
268
n.size = size(n[0]) + size(n[1]) + 1;
273
function makeComparator(indexFunc) {
274
var curIndex = size(a.root()[0]);
275
return function (n) {
276
var dir = indexFunc(curIndex);
278
curIndex -= size(n[0][1]) + 1;
281
curIndex += size(n[1][0]) + 1;
287
function insert(idx, data) {
288
arrayRep.splice(idx, 0, data);
289
var newNode = a.insert(makeComparator(function (curIndex) {
290
if (idx <= curIndex) return -1;
297
function remove(idx) {
298
arrayRep.splice(idx, 1);
299
a.remove(makeComparator(function (curIndex) {
300
return numcomp(idx, curIndex);
305
function genArray() {
307
a.forEach(function (n) { array.push(n.data); });
311
function checkRep() {
312
var array2 = genArray();
313
var str1 = array2.join(',');
314
var str2 = arrayRep.join(',');
315
if (str1 != str2) console.error(str1+" != "+str2);
317
a.forEach(function(n) {
318
if (size(n) != size(n[0]) + size(n[1]) + 1) {
319
console.error("size of "+n.data+" is wrong");
325
console.log(genArray().join(','));
336
function numcomp(a,b) { if (a < b) return -1; if (a > b) return 1; return 0; }
338
/*var tree = makeBBTree(function(a, b) { b.key = a.key; });
339
function insert(x) { tree.insert(function(n) { return numcomp(x, n.key) }).key = x; }
340
function remove(x) { tree.remove(function (n) { return numcomp(x, n.key); }); }
341
function contains(x) { return !! tree.find(function (n) { return numcomp(x, n.key); }); }
344
function recurse(t) {
345
if (! ('key' in t)) return '';
346
return '('+recurse(t[0])+','+t.key+','+recurse(t[1])+')';
348
return recurse(tree.root());
356
console.log(print());
361
console.log(print());
366
console.log(print());
371
//console.log(print());
b'\\ No newline at end of file'