Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(402)

Side by Side Diff: pkg/analysis_server/lib/src/index/b_plus_tree.dart

Issue 326123002: Node cache, binary search. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library index.b_plus_tree; 5 library index.b_plus_tree;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 8
9 9
10 /** 10 /**
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 N id = _manager.createLeaf(); 116 N id = _manager.createLeaf();
117 return new _LeafNode<K, V, N>(this, id, _maxLeafKeys); 117 return new _LeafNode<K, V, N>(this, id, _maxLeafKeys);
118 } 118 }
119 119
120 /** 120 /**
121 * Reads the [_IndexNode] with [id] from the manager. 121 * Reads the [_IndexNode] with [id] from the manager.
122 */ 122 */
123 _IndexNode<K, V, N> _readIndexNode(N id) { 123 _IndexNode<K, V, N> _readIndexNode(N id) {
124 IndexNodeData<K, N> data = _manager.readIndex(id); 124 IndexNodeData<K, N> data = _manager.readIndex(id);
125 _IndexNode<K, V, N> node = new _IndexNode<K, V, N>(this, id, _maxIndexKeys); 125 _IndexNode<K, V, N> node = new _IndexNode<K, V, N>(this, id, _maxIndexKeys);
126 node.keys.addAll(data.keys); 126 node.keys = data.keys;
127 node.children.addAll(data.children); 127 node.children = data.children;
128 return node; 128 return node;
129 } 129 }
130 130
131 /** 131 /**
132 * Reads the [_LeafNode] with [id] from the manager. 132 * Reads the [_LeafNode] with [id] from the manager.
133 */ 133 */
134 _LeafNode<K, V, N> _readLeafNode(N id) { 134 _LeafNode<K, V, N> _readLeafNode(N id) {
135 _LeafNode<K, V, N> node = new _LeafNode<K, V, N>(this, id, _maxLeafKeys); 135 _LeafNode<K, V, N> node = new _LeafNode<K, V, N>(this, id, _maxLeafKeys);
136 LeafNodeData<K, V> data = _manager.readLeaf(id); 136 LeafNodeData<K, V> data = _manager.readLeaf(id);
137 node.keys.addAll(data.keys); 137 node.keys = data.keys;
138 node.values.addAll(data.values); 138 node.values = data.values;
139 return node; 139 return node;
140 } 140 }
141 141
142 /** 142 /**
143 * Reads the [_IndexNode] or [_LeafNode] with [id] from the manager. 143 * Reads the [_IndexNode] or [_LeafNode] with [id] from the manager.
144 */ 144 */
145 _Node<K, V, N> _readNode(N id) { 145 _Node<K, V, N> _readNode(N id) {
146 if (_manager.isIndex(id)) { 146 if (_manager.isIndex(id)) {
147 return _readIndexNode(id); 147 return _readIndexNode(id);
148 } else { 148 } else {
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 * Writes information about the leaf node with the given identifier. 303 * Writes information about the leaf node with the given identifier.
304 */ 304 */
305 void writeLeaf(N id, LeafNodeData<K, V> data); 305 void writeLeaf(N id, LeafNodeData<K, V> data);
306 } 306 }
307 307
308 308
309 /** 309 /**
310 * An index node with keys and children references. 310 * An index node with keys and children references.
311 */ 311 */
312 class _IndexNode<K, V, N> extends _Node<K, V, N> { 312 class _IndexNode<K, V, N> extends _Node<K, V, N> {
313 final List<N> children = new List<N>(); 313 List<N> children = new List<N>();
314 final int maxKeys; 314 final int maxKeys;
315 final int minKeys; 315 final int minKeys;
316 316
317 _IndexNode(BPlusTree<K, V, N> tree, N id, int maxKeys) 317 _IndexNode(BPlusTree<K, V, N> tree, N id, int maxKeys)
318 : super(tree, id), 318 : super(tree, id),
319 maxKeys = maxKeys, 319 maxKeys = maxKeys,
320 minKeys = maxKeys ~/ 2; 320 minKeys = maxKeys ~/ 2;
321 321
322 @override 322 @override
323 V find(K key) { 323 V find(K key) {
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
481 _Node<K, V, N> child = tree._readNode(children[keys.length]); 481 _Node<K, V, N> child = tree._readNode(children[keys.length]);
482 child.writeOn(buffer, indent + ' '); 482 child.writeOn(buffer, indent + ' ');
483 buffer.write(indent); 483 buffer.write(indent);
484 buffer.write('}\n'); 484 buffer.write('}\n');
485 } 485 }
486 486
487 /** 487 /**
488 * Returns the index of the child into which [key] should be inserted. 488 * Returns the index of the child into which [key] should be inserted.
489 */ 489 */
490 int _findChildIndex(K key) { 490 int _findChildIndex(K key) {
491 for (int i = 0; i < keys.length; i++) { 491 int lo = 0;
Brian Wilkerson 2014/06/10 17:08:29 Seems like a good candidate for a general utility
scheglov 2014/06/10 17:23:45 Yes, in general, but they are not completely ident
492 if (comparator(keys[i], key) > 0) { 492 int hi = keys.length - 1;
493 return i; 493 while (lo <= hi) {
494 int mid = lo + (hi - lo) ~/ 2;
495 int compare = comparator(key, keys[mid]);
496 if (compare < 0) {
497 hi = mid - 1;
498 } else if (compare > 0) {
499 lo = mid + 1;
500 } else {
501 return mid + 1;
494 } 502 }
495 } 503 }
496 return keys.length; 504 return lo;
497 } 505 }
498 506
499 void _insertNotFull(K key, V value) { 507 void _insertNotFull(K key, V value) {
500 int index = _findChildIndex(key); 508 int index = _findChildIndex(key);
501 _Node<K, V, N> child = tree._readNode(children[index]); 509 _Node<K, V, N> child = tree._readNode(children[index]);
502 _Split<K, N> result = child.insert(key, value); 510 _Split<K, N> result = child.insert(key, value);
503 if (result != null) { 511 if (result != null) {
504 keys.insert(index, result.key); 512 keys.insert(index, result.key);
505 children[index] = result.left; 513 children[index] = result.left;
506 children.insert(index + 1, result.right); 514 children.insert(index + 1, result.right);
507 tree._writeIndexNode(this); 515 tree._writeIndexNode(this);
508 } 516 }
509 } 517 }
510 } 518 }
511 519
512 520
513 /** 521 /**
514 * A leaf node with keys and values. 522 * A leaf node with keys and values.
515 */ 523 */
516 class _LeafNode<K, V, N> extends _Node<K, V, N> { 524 class _LeafNode<K, V, N> extends _Node<K, V, N> {
517 final int maxKeys; 525 final int maxKeys;
518 final int minKeys; 526 final int minKeys;
519 final List<V> values = new List<V>(); 527 List<V> values = new List<V>();
520 528
521 _LeafNode(BPlusTree<K, V, N> tree, N id, int maxKeys) 529 _LeafNode(BPlusTree<K, V, N> tree, N id, int maxKeys)
522 : super(tree, id), 530 : super(tree, id),
523 maxKeys = maxKeys, 531 maxKeys = maxKeys,
524 minKeys = maxKeys ~/ 2; 532 minKeys = maxKeys ~/ 2;
525 533
526 @override 534 @override
527 V find(K key) { 535 V find(K key) {
528 int index = _findKeyIndex(key); 536 int index = _findKeyIndex(key);
529 if (index < 0) { 537 if (index < 0) {
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
638 buffer.write(': '); 646 buffer.write(': ');
639 buffer.write(values[i]); 647 buffer.write(values[i]);
640 } 648 }
641 buffer.write('}\n'); 649 buffer.write('}\n');
642 } 650 }
643 651
644 /** 652 /**
645 * Returns the index where [key] should be inserted. 653 * Returns the index where [key] should be inserted.
646 */ 654 */
647 int _findKeyIndex(K key) { 655 int _findKeyIndex(K key) {
648 for (int i = 0; i < keys.length; i++) { 656 int lo = 0;
Brian Wilkerson 2014/06/10 17:08:29 Especially since it's already been duplicated. :-)
649 if (comparator(keys[i], key) >= 0) { 657 int hi = keys.length - 1;
650 return i; 658 while (lo <= hi) {
659 int mid = lo + (hi - lo) ~/ 2;
660 int compare = comparator(key, keys[mid]);
661 if (compare < 0) {
662 hi = mid - 1;
663 } else if (compare > 0) {
664 lo = mid + 1;
665 } else {
666 return mid;
651 } 667 }
652 } 668 }
653 return keys.length; 669 return lo;
654 } 670 }
655 671
656 void _insertNotFull(K key, V value, int index) { 672 void _insertNotFull(K key, V value, int index) {
657 if (index < keys.length && keys[index] == key) { 673 if (index < keys.length && keys[index] == key) {
658 values[index] = value; 674 values[index] = value;
659 } else { 675 } else {
660 keys.insert(index, key); 676 keys.insert(index, key);
661 values.insert(index, value); 677 values.insert(index, value);
662 } 678 }
663 tree._writeLeafNode(this); 679 tree._writeLeafNode(this);
(...skipping 11 matching lines...) Expand all
675 final Comparator<K> comparator; 691 final Comparator<K> comparator;
676 692
677 /** 693 /**
678 * The identifier of this node. 694 * The identifier of this node.
679 */ 695 */
680 final N id; 696 final N id;
681 697
682 /** 698 /**
683 * The list of keys. 699 * The list of keys.
684 */ 700 */
685 final List<K> keys = new List<K>(); 701 List<K> keys = new List<K>();
686 702
687 /** 703 /**
688 * The [NodeManager] for this tree. 704 * The [NodeManager] for this tree.
689 */ 705 */
690 final NodeManager<K, V, N> manager; 706 final NodeManager<K, V, N> manager;
691 707
692 /** 708 /**
693 * The [BPlusTree] this node belongs to. 709 * The [BPlusTree] this node belongs to.
694 */ 710 */
695 final BPlusTree<K, V, N> tree; 711 final BPlusTree<K, V, N> tree;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 765
750 /** 766 /**
751 * A container with information about split during insert. 767 * A container with information about split during insert.
752 */ 768 */
753 class _Split<K, N> { 769 class _Split<K, N> {
754 final K key; 770 final K key;
755 final N left; 771 final N left;
756 final N right; 772 final N right;
757 _Split(this.key, this.left, this.right); 773 _Split(this.key, this.left, this.right);
758 } 774 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analysis_server/lib/src/index/lru_cache.dart » ('j') | pkg/analysis_server/lib/src/index/lru_cache.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698