| OLD | NEW |
| 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 test.index.b_plus_tree; | 5 library test.index.b_plus_tree; |
| 6 | 6 |
| 7 import 'dart:math'; | 7 import 'dart:math'; |
| 8 | 8 |
| 9 import 'package:analysis_server/src/index/b_plus_tree.dart'; | 9 import 'package:analysis_server/src/index/b_plus_tree.dart'; |
| 10 import 'package:unittest/unittest.dart'; | 10 import 'package:unittest/unittest.dart'; |
| 11 | 11 |
| 12 import '../reflective_tests.dart'; | 12 import '../reflective_tests.dart'; |
| 13 | 13 |
| 14 | 14 |
| 15 main() { | 15 main() { |
| 16 groupSep = ' | '; | 16 groupSep = ' | '; |
| 17 group('BTree', () { | 17 group('BTree', () { |
| 18 runReflectiveTests(BPlusTreeTest); | 18 runReflectiveTests(BPlusTreeTest); |
| 19 }); | 19 }); |
| 20 } | 20 } |
| 21 | 21 |
| 22 | 22 |
| 23 void _assertDebugString(BPlusTree tree, String expected) { | 23 void _assertDebugString(BPlusTree tree, String expected) { |
| 24 String dump = _getDebugString(tree); | 24 String dump = _getDebugString(tree); |
| 25 expect(dump, expected); | 25 expect(dump, expected); |
| 26 } | 26 } |
| 27 | 27 |
| 28 | 28 |
| 29 _TestBTree<int, String> _createTree(int maxIndexKeys, int maxLeafKeys) { |
| 30 return new _TestBTree<int, String>(maxIndexKeys, maxLeafKeys, _intComparator); |
| 31 } |
| 32 |
| 33 |
| 29 String _getDebugString(BPlusTree tree) { | 34 String _getDebugString(BPlusTree tree) { |
| 30 StringBuffer buffer = new StringBuffer(); | 35 StringBuffer buffer = new StringBuffer(); |
| 31 tree.writeOn(buffer); | 36 tree.writeOn(buffer); |
| 32 return buffer.toString(); | 37 return buffer.toString(); |
| 33 } | 38 } |
| 34 | 39 |
| 35 | 40 |
| 36 int _intComparator(int a, int b) => a - b; | 41 int _intComparator(int a, int b) => a - b; |
| 37 | 42 |
| 38 | 43 |
| 39 @ReflectiveTestCase() | 44 @ReflectiveTestCase() |
| 40 class BPlusTreeTest { | 45 class BPlusTreeTest { |
| 41 BPlusTree<int, String> tree = new BPlusTree<int, String>(4, 4, _intComparator)
; | 46 BPlusTree<int, String, dynamic> tree = _createTree(4, 4); |
| 42 | 47 |
| 43 test_NoSuchMethodError() { | 48 test_NoSuchMethodError() { |
| 44 expect(() { | 49 expect(() { |
| 45 (tree as dynamic).thereIsNoSuchMethod(); | 50 (tree as dynamic).thereIsNoSuchMethod(); |
| 46 }, throwsA(new isInstanceOf<NoSuchMethodError>())); | 51 }, throwsA(new isInstanceOf<NoSuchMethodError>())); |
| 47 } | 52 } |
| 48 | 53 |
| 49 void test_find() { | 54 void test_find() { |
| 50 _insertValues(12); | 55 _insertValues(12); |
| 51 expect(tree.find(-1), isNull); | 56 expect(tree.find(-1), isNull); |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 _insert(1, 'B'); | 169 _insert(1, 'B'); |
| 165 _insert(2, 'C'); | 170 _insert(2, 'C'); |
| 166 _assertDebugString(tree, 'LNode {0: A, 1: B, 2: C}\n'); | 171 _assertDebugString(tree, 'LNode {0: A, 1: B, 2: C}\n'); |
| 167 _insert(2, 'C2'); | 172 _insert(2, 'C2'); |
| 168 _insert(1, 'B2'); | 173 _insert(1, 'B2'); |
| 169 _insert(0, 'A2'); | 174 _insert(0, 'A2'); |
| 170 _assertDebugString(tree, 'LNode {0: A2, 1: B2, 2: C2}\n'); | 175 _assertDebugString(tree, 'LNode {0: A2, 1: B2, 2: C2}\n'); |
| 171 } | 176 } |
| 172 | 177 |
| 173 void test_remove_inner_borrowLeft() { | 178 void test_remove_inner_borrowLeft() { |
| 174 tree = new BPlusTree<int, String>(10, 4, _intComparator); | 179 tree = _createTree(10, 4); |
| 175 for (int i = 100; i < 125; i++) { | 180 for (int i = 100; i < 125; i++) { |
| 176 _insert(i, 'V$i'); | 181 _insert(i, 'V$i'); |
| 177 } | 182 } |
| 178 for (int i = 0; i < 10; i++) { | 183 for (int i = 0; i < 10; i++) { |
| 179 _insert(i, 'V$i'); | 184 _insert(i, 'V$i'); |
| 180 } | 185 } |
| 181 _assertDebugString(tree, ''' | 186 _assertDebugString(tree, ''' |
| 182 INode { | 187 INode { |
| 183 INode { | 188 INode { |
| 184 LNode {0: V0, 1: V1} | 189 LNode {0: V0, 1: V1} |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 251 120 | 256 120 |
| 252 LNode {120: V120, 121: V121} | 257 LNode {120: V120, 121: V121} |
| 253 122 | 258 122 |
| 254 LNode {122: V122, 123: V123, 124: V124} | 259 LNode {122: V122, 123: V123, 124: V124} |
| 255 } | 260 } |
| 256 } | 261 } |
| 257 '''); | 262 '''); |
| 258 } | 263 } |
| 259 | 264 |
| 260 void test_remove_inner_borrowRight() { | 265 void test_remove_inner_borrowRight() { |
| 261 tree = new BPlusTree<int, String>(10, 4, _intComparator); | 266 tree = _createTree(10, 4); |
| 262 for (int i = 100; i < 135; i++) { | 267 for (int i = 100; i < 135; i++) { |
| 263 _insert(i, 'V$i'); | 268 _insert(i, 'V$i'); |
| 264 } | 269 } |
| 265 _assertDebugString(tree, ''' | 270 _assertDebugString(tree, ''' |
| 266 INode { | 271 INode { |
| 267 INode { | 272 INode { |
| 268 LNode {100: V100, 101: V101} | 273 LNode {100: V100, 101: V101} |
| 269 102 | 274 102 |
| 270 LNode {102: V102, 103: V103} | 275 LNode {102: V102, 103: V103} |
| 271 104 | 276 104 |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 473 } | 478 } |
| 474 | 479 |
| 475 void test_remove_leafRoot_notFound() { | 480 void test_remove_leafRoot_notFound() { |
| 476 _insertValues(1); | 481 _insertValues(1); |
| 477 _assertDebugString(tree, 'LNode {0: V0}\n'); | 482 _assertDebugString(tree, 'LNode {0: V0}\n'); |
| 478 expect(tree.remove(10), null); | 483 expect(tree.remove(10), null); |
| 479 _assertDebugString(tree, 'LNode {0: V0}\n'); | 484 _assertDebugString(tree, 'LNode {0: V0}\n'); |
| 480 } | 485 } |
| 481 | 486 |
| 482 void test_remove_leaf_borrowLeft() { | 487 void test_remove_leaf_borrowLeft() { |
| 483 tree = new BPlusTree<int, String>(10, 10, _intComparator); | 488 tree = _createTree(10, 10); |
| 484 for (int i = 20; i < 40; i++) { | 489 for (int i = 20; i < 40; i++) { |
| 485 _insert(i, 'V$i'); | 490 _insert(i, 'V$i'); |
| 486 } | 491 } |
| 487 for (int i = 0; i < 5; i++) { | 492 for (int i = 0; i < 5; i++) { |
| 488 _insert(i, 'V$i'); | 493 _insert(i, 'V$i'); |
| 489 } | 494 } |
| 490 _assertDebugString(tree, ''' | 495 _assertDebugString(tree, ''' |
| 491 INode { | 496 INode { |
| 492 LNode {0: V0, 1: V1, 2: V2, 3: V3, 4: V4, 20: V20, 21: V21, 22: V22, 23: V23
, 24: V24} | 497 LNode {0: V0, 1: V1, 2: V2, 3: V3, 4: V4, 20: V20, 21: V21, 22: V22, 23: V23
, 24: V24} |
| 493 25 | 498 25 |
| 494 LNode {25: V25, 26: V26, 27: V27, 28: V28, 29: V29} | 499 LNode {25: V25, 26: V26, 27: V27, 28: V28, 29: V29} |
| 495 30 | 500 30 |
| 496 LNode {30: V30, 31: V31, 32: V32, 33: V33, 34: V34, 35: V35, 36: V36, 37: V3
7, 38: V38, 39: V39} | 501 LNode {30: V30, 31: V31, 32: V32, 33: V33, 34: V34, 35: V35, 36: V36, 37: V3
7, 38: V38, 39: V39} |
| 497 } | 502 } |
| 498 '''); | 503 '''); |
| 499 expect(tree.remove(25), 'V25'); | 504 expect(tree.remove(25), 'V25'); |
| 500 _assertDebugString(tree, ''' | 505 _assertDebugString(tree, ''' |
| 501 INode { | 506 INode { |
| 502 LNode {0: V0, 1: V1, 2: V2, 3: V3, 4: V4, 20: V20, 21: V21} | 507 LNode {0: V0, 1: V1, 2: V2, 3: V3, 4: V4, 20: V20, 21: V21} |
| 503 22 | 508 22 |
| 504 LNode {22: V22, 23: V23, 24: V24, 26: V26, 27: V27, 28: V28, 29: V29} | 509 LNode {22: V22, 23: V23, 24: V24, 26: V26, 27: V27, 28: V28, 29: V29} |
| 505 30 | 510 30 |
| 506 LNode {30: V30, 31: V31, 32: V32, 33: V33, 34: V34, 35: V35, 36: V36, 37: V3
7, 38: V38, 39: V39} | 511 LNode {30: V30, 31: V31, 32: V32, 33: V33, 34: V34, 35: V35, 36: V36, 37: V3
7, 38: V38, 39: V39} |
| 507 } | 512 } |
| 508 '''); | 513 '''); |
| 509 } | 514 } |
| 510 | 515 |
| 511 void test_remove_leaf_borrowRight() { | 516 void test_remove_leaf_borrowRight() { |
| 512 tree = new BPlusTree<int, String>(10, 10, _intComparator); | 517 tree = _createTree(10, 10); |
| 513 _insertValues(15); | 518 _insertValues(15); |
| 514 _assertDebugString(tree, ''' | 519 _assertDebugString(tree, ''' |
| 515 INode { | 520 INode { |
| 516 LNode {0: V0, 1: V1, 2: V2, 3: V3, 4: V4} | 521 LNode {0: V0, 1: V1, 2: V2, 3: V3, 4: V4} |
| 517 5 | 522 5 |
| 518 LNode {5: V5, 6: V6, 7: V7, 8: V8, 9: V9, 10: V10, 11: V11, 12: V12, 13: V13
, 14: V14} | 523 LNode {5: V5, 6: V6, 7: V7, 8: V8, 9: V9, 10: V10, 11: V11, 12: V12, 13: V13
, 14: V14} |
| 519 } | 524 } |
| 520 '''); | 525 '''); |
| 521 expect(tree.remove(0), 'V0'); | 526 expect(tree.remove(0), 'V0'); |
| 522 _assertDebugString(tree, ''' | 527 _assertDebugString(tree, ''' |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 625 // remove even, forward | 630 // remove even, forward |
| 626 for (int i = 0; i < count; i += 2) { | 631 for (int i = 0; i < count; i += 2) { |
| 627 tree.remove(i); | 632 tree.remove(i); |
| 628 } | 633 } |
| 629 for (int i = 0; i < count; i++) { | 634 for (int i = 0; i < count; i++) { |
| 630 expect(tree.find(i), isNull); | 635 expect(tree.find(i), isNull); |
| 631 } | 636 } |
| 632 } | 637 } |
| 633 | 638 |
| 634 void test_stress_random() { | 639 void test_stress_random() { |
| 635 tree = new BPlusTree<int, String>(10, 10, _intComparator); | 640 tree = _createTree(10, 10); |
| 636 int maxKey = 1000000; | 641 int maxKey = 1000000; |
| 637 int tryCount = 1000; | 642 int tryCount = 1000; |
| 638 Set<int> keys = new Set<int>(); | 643 Set<int> keys = new Set<int>(); |
| 639 { | 644 { |
| 640 Random random = new Random(); | 645 Random random = new Random(); |
| 641 for (int i = 0; i < tryCount; i++) { | 646 for (int i = 0; i < tryCount; i++) { |
| 642 int key = random.nextInt(maxKey); | 647 int key = random.nextInt(maxKey); |
| 643 keys.add(key); | 648 keys.add(key); |
| 644 _insert(key, 'V$key'); | 649 _insert(key, 'V$key'); |
| 645 } | 650 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 667 void _insert(int key, String value) { | 672 void _insert(int key, String value) { |
| 668 tree.insert(key, value); | 673 tree.insert(key, value); |
| 669 } | 674 } |
| 670 | 675 |
| 671 void _insertValues(int count) { | 676 void _insertValues(int count) { |
| 672 for (int i = 0; i < count; i++) { | 677 for (int i = 0; i < count; i++) { |
| 673 _insert(i, 'V$i'); | 678 _insert(i, 'V$i'); |
| 674 } | 679 } |
| 675 } | 680 } |
| 676 } | 681 } |
| 682 |
| 683 class _TestBTree<K, V> extends BPlusTree<K, V, int> { |
| 684 _TestBTree(int maxIndexKeys, int maxLeafKeys, Comparator<K> comparator) : |
| 685 super(maxIndexKeys, maxLeafKeys, comparator, new MemoryNodeManager()); |
| 686 } |
| OLD | NEW |