1 /* 2 * Hunt - A refined core library for D programming language. 3 * 4 * Copyright (C) 2018-2019 HuntLabs 5 * 6 * Website: https://www.huntlabs.net/ 7 * 8 * Licensed under the Apache-2.0 License. 9 * 10 */ 11 12 module hunt.collection.Radix; 13 14 import std.stdio; 15 import core.memory; 16 import core.stdc.string; 17 import core.stdc.stdlib; 18 19 20 private: 21 22 void debug_log( A ...)( A args){ 23 return; 24 } 25 alias log_info = debug_log; 26 alias log_error = debug_log; 27 28 struct raxNode 29 { 30 uint args; 31 // 1 iskey 32 // 1 isnull don't store it 33 // 1 iscompr 34 // 29 size 35 36 //void *data; 37 38 // node is not compr 39 // [abc][a-ptr][b-ptr][c-ptr](value-ptr?) 40 // 41 // node is compr 42 // [xyz][z-ptr](value-ptr?) 43 pragma(inline, true): 44 45 @property char *str() 46 { 47 return cast(char*)(&this + 1); 48 } 49 50 @property bool iskey() 51 { 52 return cast(bool)(args & 0x80000000); 53 } 54 55 @property bool iskey(bool value) 56 { 57 if(value) 58 args = args | 0x80000000; 59 else 60 args = args & (~0x80000000); 61 62 return value; 63 } 64 65 @property bool isnull() 66 { 67 return cast(bool)(args & 0x40000000); 68 } 69 70 @property bool isnull( bool value) 71 { 72 if(value) 73 args = args| 0x40000000; 74 else 75 args = args & (~0x40000000); 76 77 return value; 78 } 79 80 @property bool iscompr() 81 { 82 return cast(bool)(args & 0x20000000); 83 } 84 85 @property bool iscompr( bool value) 86 { 87 if(value) 88 args = args | 0x20000000; 89 else 90 args = args & (~0x20000000); 91 92 return value; 93 } 94 95 96 97 98 @property uint size() 99 { 100 return args & 0x1FFFFFFF; 101 } 102 103 @property uint size(uint value) 104 { 105 uint v = args & (~0x1FFFFFFF); 106 v += value; 107 args = v; 108 return value; 109 } 110 111 @property raxNode** orgin() 112 { 113 return cast(raxNode**)(str+size); 114 } 115 116 @property raxNode * next() 117 { 118 return *orgin; 119 } 120 121 @property raxNode *next(raxNode *n) 122 { 123 *orgin = n; 124 return n; 125 } 126 127 128 129 130 @property raxNode * nextChild(uint index) 131 { 132 if(index >= size) 133 log_error( index , " " , size); 134 return orgin[index]; 135 } 136 137 @property raxNode *nextChild(uint index , raxNode *n) 138 { 139 orgin[index] = n; 140 return n; 141 } 142 143 144 145 @property void *value() 146 { 147 if(iscompr) 148 return orgin[1]; 149 else 150 return orgin[size]; 151 } 152 153 154 @property void * value(void *v) 155 { 156 if(iscompr) 157 orgin[1] = cast(raxNode *)v; 158 else 159 orgin[size] = cast(raxNode *)v; 160 return v; 161 } 162 163 164 165 166 pragma(inline, false): 167 //alloc non-compr node 168 static raxNode* New(uint children , bool hasdata) 169 { 170 171 long nodesize = raxNode.sizeof + children + (raxNode*).sizeof * children; 172 if(hasdata) 173 nodesize += (void*).sizeof; 174 175 raxNode *n = cast(raxNode*)malloc(cast(size_t)nodesize); 176 if( n is null) return null; 177 178 n.iskey = false; 179 n.isnull = false; 180 n.iscompr = false; 181 n.size = children; 182 183 return n; 184 } 185 186 static raxNode *NewComp(uint length , bool hasdata) 187 { 188 189 long nodesize = raxNode.sizeof + length + (raxNode *).sizeof; 190 if(hasdata) 191 nodesize += (void *).sizeof; 192 193 raxNode *n = cast(raxNode*)malloc(cast(size_t)nodesize); 194 if( n is null) return null; 195 196 n.iskey = false; 197 n.isnull = false; 198 n.iscompr = true; 199 n.size = length; 200 201 202 return n; 203 204 } 205 206 207 static raxNode *Renew(raxNode *n , uint children , bool hasdata) 208 { 209 long nodesize = raxNode.sizeof + children + (raxNode*).sizeof * children; 210 if(hasdata) 211 nodesize += (void *).sizeof; 212 213 214 auto node = cast(raxNode*)realloc(n ,cast(size_t) nodesize); 215 if(node is null) return null; 216 node.iscompr = false; 217 return node; 218 } 219 220 221 static raxNode *RenewComp(raxNode *n , uint length , bool hasdata) 222 { 223 224 long nodesize= raxNode.sizeof + length + (raxNode*).sizeof * length; 225 if(hasdata) 226 nodesize += (void *).sizeof; 227 228 auto node = cast(raxNode*) realloc(n , cast(size_t)nodesize); 229 if( node is null) return null; 230 node.iscompr = true; 231 return node; 232 } 233 234 static void Free(raxNode *n) 235 { 236 free(n); 237 } 238 239 240 241 242 } 243 244 struct raxItem 245 { 246 raxNode *n; 247 int index; 248 } 249 250 251 public: 252 253 struct rax 254 { 255 protected raxNode *head; 256 protected long numnodes; 257 long numele; 258 259 // 260 // api New 261 // 262 static rax * New() 263 { 264 rax *r = cast(rax *)malloc(rax.sizeof); 265 if (r is null) return null; 266 267 r.numele = 0; 268 r.numnodes = 1; 269 r.head = raxNode.NewComp(0 , false); 270 271 if (r.head is null) 272 { 273 Free(r); 274 return null; 275 } 276 else 277 { 278 return r; 279 } 280 } 281 282 283 284 285 286 // 287 // api Free 288 // 289 static void Free(rax *r) 290 { 291 r.RecursiveFree(r.head); 292 free(r); 293 } 294 295 // 296 // api Clear 297 // 298 void Clear(){ 299 300 RecursiveFree(head); 301 302 numele = 0; 303 numnodes = 1; 304 head = raxNode.NewComp(0 , false); 305 306 } 307 308 // 309 // api Remove 310 // 311 bool Remove(const ubyte[] s) 312 { 313 raxNode *h = head; 314 raxNode *p = head; 315 raxItem[] ts; 316 uint index = 0; 317 uint splitpos = 0; 318 uint last = find(s , h , p , index , splitpos , ts); 319 if(last > 0){ 320 log_error("remove " , cast(string)s , " " ,last); 321 return false; 322 } 323 else{ 324 if(h.iskey) { 325 numele--; 326 h.iskey = false; 327 if(h.size == 0) 328 { 329 330 if( p.iscompr) 331 { 332 //#1 最后一个节点为空 父节点压缩节点 且是key 则去除父节点 333 // (x) 334 // | - 'test' (x) 335 // ('test') -------------> | 336 // | () 337 // () 338 // 339 340 if(p.iskey) 341 { 342 h.iskey = true; 343 h.value = p.value; 344 if(p == head) 345 { 346 head = h; 347 348 } 349 else 350 { 351 raxItem item = ts[$ - 2]; 352 item.n.nextChild(item.index , h); 353 } 354 numnodes -= 1; 355 raxNode.Free(p); 356 log_info("#####r1"); 357 } 358 //#2 最后一个节点为空 父节点是压缩节点 不是key 父父节点必须是非压缩节点 359 // (t) 360 // | 361 // (A) 362 // | 363 // ['xyz'] 364 // / \ - 'test' 365 // (B) ('test') ----------------> 366 // | | 367 // (C) () 368 // 369 // 370 // #1 当['xy'] size == 2 371 // #1 当['xy']不是key,A为压缩节点 && 当B为压缩节点 且不是key,合并三项 372 // (t) 373 // | 374 // (A) 375 // | 376 // ['xy'] 377 // / \ - 'test' (t) 378 // (B) ('test') ----------------> | 379 // | | (A + 'x' + B) 380 // (C) () | 381 // (C) 382 // 383 // #2 当['xy']不是key,A为压缩节点 , 合并两项 384 // (t) 385 // | 386 // (A) 387 // | 388 // ['xy'] 389 // / \ - 'test' (t) 390 // (B) ('test') ----------------> | 391 // | | ( A + 'x') 392 // (C) () | 393 // (B) 394 // | 395 // (C) 396 // 397 // #3 当B为压缩节点 且不是key , 合并两项 398 // (t) 399 // | 400 // (A) 401 // | (t) 402 // ['xy'] | 403 // / \ - 'test' (A) 404 // (B) ('test') ----------------> | 405 // | | ( 'x' + B) 406 // (C) () | 407 // (C) 408 // 409 // #4 当都不能合并时 410 // (t) 411 // | 412 // (A) 413 // | (t) 414 // ['xy'] | 415 // / \ - 'test' (A) 416 // (B) ('test') ----------------> | 417 // | | ( 'x') 418 // (C) () | 419 // (B) 420 // | 421 // (C) 422 else // pp exist. & pp is non compr 423 { 424 //pp 425 if( p == head) 426 { 427 head = h; 428 numnodes -= 1; 429 log_info("#####r2"); 430 } 431 else{ 432 raxItem t1 = ts[$ - 2]; 433 raxNode *r1 = ts[$ - 2].n; 434 if( r1.size == 2){ 435 436 raxNode *pp = null; 437 if(ts.length >= 3) 438 pp = ts[$ - 3].n; 439 bool ppCombine = pp && pp.iscompr && !r1.iskey; 440 raxNode *nh = r1.nextChild(r1.size - 1 - t1.index); 441 bool nhCombie = nh.iscompr && !nh.iskey; 442 443 444 445 if( ppCombine && nhCombie) 446 { 447 bool hasdata = pp.iskey && !pp.isnull; 448 raxNode *u = raxNode.NewComp(pp.size + nh.size + 1 , hasdata); 449 memcpy(u.str , pp.str , pp.size); 450 memcpy(u.str + pp.size , r1.str + r1.size - 1 - t1.index , 1); 451 memcpy(u.str + pp.size + 1 , nh.str , nh.size); 452 453 u.iskey = pp.iskey; 454 if(hasdata) 455 { 456 u.value = pp.value; 457 } 458 u.next( nh.next); 459 if( pp == head) 460 { 461 head = u; 462 } 463 else{ 464 raxItem item = ts[$ - 4]; 465 item.n.nextChild(item.index , u); 466 } 467 raxNode.Free(nh); 468 raxNode.Free(pp); 469 raxNode.Free(p); 470 raxNode.Free(h); 471 raxNode.Free(r1); 472 numnodes -= 4; 473 log_info("#####r211"); 474 475 } 476 else if(ppCombine) 477 { 478 bool hasdata = pp.iskey && !pp.isnull; 479 raxNode *u = raxNode.NewComp(pp.size + 1 , hasdata); 480 memcpy(u.str , pp.str , pp.size); 481 memcpy(u.str + pp.size , r1.str+ r1.size - 1 - t1.index , 1); 482 u.next(nh); 483 u.iskey = pp.iskey; 484 if(hasdata) 485 { 486 u.value = pp.value; 487 } 488 489 if( pp == head) 490 { 491 head = u; 492 } 493 else{ 494 raxItem item = ts[$ - 4]; 495 item.n.nextChild(item.index , u); 496 } 497 raxNode.Free(pp); 498 raxNode.Free(p); 499 raxNode.Free(h); 500 raxNode.Free(r1); 501 numnodes -= 3; 502 503 log_info("#####r212"); 504 } 505 else if(nhCombie) 506 { 507 bool hasdata = r1.iskey && !r1.isnull; 508 raxNode* u = raxNode.NewComp(1 + nh.size , hasdata); 509 memcpy(u.str , r1.str + r1.size - 1 - t1.index , 1); 510 memcpy(u.str + 1, nh.str , nh.size); 511 u.iskey = r1.iskey; 512 513 if(hasdata) 514 { 515 u.value = r1.value; 516 } 517 518 u.next(nh.next); 519 520 521 if( r1 == head) 522 { 523 head = u; 524 } 525 else 526 { 527 raxItem item = ts[$ - 3]; 528 log_info(getStr(item.n)); 529 item.n.nextChild(item.index , u); 530 } 531 raxNode.Free(nh); 532 raxNode.Free(p); 533 raxNode.Free(h); 534 raxNode.Free(r1); 535 numnodes -= 3; 536 log_info("#####r213"); 537 } 538 else{ 539 bool hasdata = r1.iskey && !r1.isnull; 540 raxNode *n = raxNode.NewComp(1 , hasdata); 541 n.iskey = r1.iskey; 542 if(hasdata) 543 n.value = r1.value; 544 n.str[0] = r1.str[r1.size - 1 - t1.index]; 545 n.next( r1.nextChild(r1.size - 1 - t1.index)); 546 547 if(r1 == head) 548 { 549 head = n; 550 } 551 else{ 552 raxItem item = ts[$ - 3]; 553 item.n.nextChild(item.index , n); 554 } 555 556 raxNode.Free(h); 557 raxNode.Free(p); 558 raxNode.Free(r1); 559 numnodes -= 2; 560 log_info("#####r214"); 561 } 562 563 564 } 565 // #1 当['xyz'] 的size > 2 566 // 567 // (t) (t) 568 // | | 569 // (A) (A) 570 // | | 571 // ['xyz'] ['xz'] 572 // / \ \ - 'test' / \ 573 // (B)('test') (D) ----------------> ('B') (D) 574 // | | 575 // (C) () 576 // 577 else if (r1.size > 2){ 578 579 bool hasdata = r1.iskey && !r1.isnull; 580 raxNode *u = raxNode.New(r1.size - 1, hasdata); 581 u.iskey = r1.iskey; 582 if(hasdata) 583 { 584 u.value = r1.value; 585 } 586 587 log_info("index " , t1.index , " " , r1.size); 588 589 if( t1.index == 0) 590 { 591 memcpy(u.str , r1.str + 1 , r1.size - 1 ); 592 593 } 594 else if(t1.index == r1.size - 1) 595 { 596 memcpy(u.str , r1.str , r1.size - 1); 597 } 598 else 599 { 600 memcpy(u.str , r1.str , t1.index); 601 memcpy(u.str + t1.index , r1.str + t1.index + 1, r1.size - t1.index -1); 602 } 603 604 log_info(getStr(u)); 605 606 for( uint i , j = 0 ; i < r1.size ; ) 607 { 608 if( i != t1.index) 609 u.orgin[j++] = r1.orgin[i++]; 610 else 611 i++; 612 } 613 614 //raxNode *test = null; 615 616 if(r1 == head) 617 { 618 head = u; 619 } 620 else{ 621 raxItem i = ts[$ - 3]; 622 623 i.n.nextChild(i.index , u); 624 625 } 626 627 raxNode.Free(r1); 628 raxNode.Free(h); 629 raxNode.Free(p); 630 631 numnodes -= 2; 632 log_info("####r22"); 633 634 } 635 else{ 636 log_error("####r23 none exist"); 637 } 638 } 639 } 640 } 641 // #3 当父节点为非压缩节点 642 // 643 // 644 // (A) 645 // | A+'y' 646 // ['xyz'] -----------> 647 // / | \ 648 // (C) () (D) 649 // 650 // 651 // 652 // #1 当['xy'] 的size == 2时 653 // 654 // 当#1 ['xy']非key,且(C)非key , 合并三项 655 // (t) 656 // | 657 // (A) 658 // | A+'y' (t) 659 // ['xy'] -----------> | 660 // / | (A + 'x' + C) 661 // (C) () | 662 // | (D) 663 // (D) 664 // 665 // 666 // 667 // 当#2 ['xy']非key , 合并两项 668 // (t) 669 // | 670 // (A) 671 // | A+'y' (t) 672 // ['xy'] -----------> | 673 // / | (A + 'x' ) 674 // (C) () | 675 // | (C) 676 // (D) | 677 // (D) 678 // 当#3 (C)非key , 合并两项 679 // (t) 680 // | (t) 681 // (A) | 682 // | A+'y' (A) 683 // ['xy'] -----------> | 684 // / | ('x' + C) 685 // (C) () | 686 // | (D) 687 // (D) 688 // 689 // 当#4 无合并 690 // 691 // (t) 692 // | (t) 693 // (A) | 694 // | A+'y' (A) 695 // ['xy'] -----------> | 696 // / | ('x') 697 // (C) () | 698 // | (C) 699 // (D) | 700 // (D) 701 else if(!p.iscompr) 702 { 703 // noncompr to compr 704 log_info("p " , getStr(p)); 705 if(p.size == 2){ 706 707 raxNode *pp = null ; 708 if(ts.length >= 2) 709 pp = ts[$ - 2].n; 710 bool ppCombine = pp && pp.iscompr && !p.iskey; 711 raxNode *nh = p.nextChild(p.size - 1 - index); 712 713 log_info("nh " , getStr(nh)); 714 bool nhCombie = nh.iscompr && !nh.iskey; 715 716 log_info(ppCombine , " " , nhCombie); 717 718 // #1 合并3个 719 if( ppCombine && nhCombie) 720 { 721 bool hasdata = pp.iskey && !pp.isnull; 722 raxNode *u = raxNode.NewComp(pp.size + nh.size + 1 , hasdata); 723 memcpy(u.str , pp.str , pp.size); 724 memcpy(u.str + pp.size , p.str + p.size - 1 - index , 1); 725 memcpy(u.str + pp.size + 1 , nh.str , nh.size); 726 727 u.iskey = pp.iskey; 728 if(hasdata) 729 u.value = pp.value; 730 731 u.next( nh.next); 732 if( pp == head) 733 { 734 head = u; 735 } 736 else{ 737 raxItem item = ts[$ - 3]; 738 item.n.nextChild(item.index , u); 739 } 740 raxNode.Free(nh); 741 raxNode.Free(pp); 742 raxNode.Free(p); 743 raxNode.Free(h); 744 745 numnodes -= 3; 746 747 log_info("#####r311"); 748 } 749 // #2 750 else if(ppCombine) 751 { 752 753 bool hasdata = pp.iskey && !pp.isnull; 754 raxNode *u = raxNode.NewComp(pp.size + 1 , hasdata); 755 memcpy(u.str , pp.str , pp.size); 756 memcpy(u.str + pp.size , p.str+ p.size - 1 - index , 1); 757 u.next(nh); 758 u.iskey = pp.iskey; 759 if(hasdata) 760 u.value = pp.value; 761 762 if( pp == head) 763 { 764 head = u; 765 } 766 else{ 767 raxItem item = ts[$ - 3]; 768 item.n.nextChild(item.index , u); 769 } 770 raxNode.Free(pp); 771 raxNode.Free(p); 772 raxNode.Free(h); 773 numnodes -= 2; 774 775 log_info("#####r312"); 776 } 777 else if(nhCombie) 778 { 779 bool hasdata = p.iskey && !p.isnull; 780 raxNode* u = raxNode.NewComp(1 + nh.size , hasdata); 781 memcpy(u.str , p.str + p.size - 1 - index , 1); 782 memcpy(u.str + 1, nh.str , nh.size); 783 u.iskey = p.iskey; 784 u.next(nh.next); 785 if(hasdata) 786 u.value = p.value; 787 if( p == head) 788 { 789 head = u; 790 } 791 else 792 { 793 raxItem item = ts[$ - 2]; 794 item.n.nextChild(item.index , u); 795 } 796 raxNode.Free(nh); 797 raxNode.Free(p); 798 raxNode.Free(h); 799 numnodes -= 2; 800 log_info("#####r313"); 801 } 802 // p.iskey or no combine. 803 else{ 804 bool hasdata = p.iskey && !p.isnull; 805 raxNode *n = raxNode.NewComp(1 , hasdata); 806 n.iskey = p.iskey; 807 if(hasdata) 808 n.value = p.value; 809 n.str[0] = p.str[p.size - 1 - index]; 810 n.next( p.nextChild(p.size - 1 - index)); 811 812 if(p == head) 813 { 814 head = n; 815 } 816 else{ 817 raxItem item = ts[$ - 2]; 818 item.n.nextChild(item.index , n); 819 } 820 821 raxNode.Free(h); 822 raxNode.Free(p); 823 numnodes -= 1; 824 log_info("#####r314"); 825 } 826 827 } 828 // #2 当['xyz'] 的size > 2时 829 // (A) (A) 830 // | A+'y' | 831 // ['xyz'] -----------> ['xz'] 832 // / | \ / \ 833 // (C) () (D) (C) (D) 834 // 835 // 836 // 837 838 else if(p.size > 2){ 839 840 bool hasdata = p.iskey && !p.isnull; 841 raxNode *u = raxNode.New(p.size - 1, hasdata); 842 u.iskey = p.iskey; 843 if(hasdata) 844 { 845 u.value = p.value; 846 } 847 848 log_info("index " , index , " " , p.size); 849 850 if( index == 0) 851 { 852 memcpy(u.str , p.str + 1 , p.size - 1 ); 853 } 854 else if(index == p.size - 1) 855 { 856 memcpy(u.str , p.str , p.size - 1); 857 } 858 else 859 { 860 memcpy(u.str , p.str , index); 861 memcpy(u.str + index , p.str + index + 1, p.size - index -1); 862 } 863 864 for( uint i , j = 0 ; i < p.size ; ) 865 { 866 if( i != index) 867 u.orgin[j++] = p.orgin[i++]; 868 else 869 i++; 870 } 871 872 if(p == head) 873 { 874 head = u; 875 } 876 else{ 877 raxItem item = ts[$ - 2]; 878 item.n.nextChild(item.index , u); 879 } 880 881 882 raxNode.Free(h); 883 raxNode.Free(p); 884 numnodes--; 885 log_info("#####r32"); 886 } 887 } 888 } 889 // h.size > 0 890 else{ 891 // #4 节点是压缩节点 , 则合并 892 // (A) (A + 'test') 893 // | | 894 // ('test') - 'test' (B) 895 // | 896 // (B) -----------> 897 // 898 // 899 // #5 只是去掉一个值。 900 901 if(h.iscompr && p.iscompr) 902 { 903 bool hasdata = p.iskey && !p.isnull; 904 raxNode *u = raxNode.NewComp(p.size + h.size , hasdata); 905 u.iskey = p.iskey; 906 if(hasdata) 907 { 908 u.value = p.value; 909 } 910 911 memcpy(u.str , p.str , p.size); 912 memcpy(u.str + p.size , h.str , h.size); 913 u.next(h.next); 914 if(p == head) 915 { 916 head = u; 917 } 918 else 919 { 920 raxItem item = ts[$ - 2]; 921 item.n.nextChild(item.index , u); 922 } 923 numnodes--; 924 raxNode.Free(p); 925 raxNode.Free(h); 926 log_info("#####r4"); 927 } 928 else{ 929 log_info("#####r5"); 930 } 931 932 } 933 return true; 934 } 935 else{ 936 log_error(cast(string)s , " is not key " , getStr(h)); 937 return false; 938 } 939 } 940 941 } 942 943 // 944 // api Insert 945 // 946 int Insert(const ubyte[] s , void *data ) 947 { 948 raxNode *h = head; 949 raxNode *p = head; 950 raxItem [] ts; 951 uint index = 0; 952 uint splitpos = 0; 953 numele++; 954 uint last = find(s , h , p , index , splitpos , ts); 955 956 log_info("find " ,cast(string)s , " last ", last , " split " , splitpos ," index " , index); 957 958 //没有找到该s. 959 if (last > 0) 960 { 961 // #1 如果该树是空树. 962 // 963 // 'test' 964 // () ----------->('test') 965 // | 966 // () 967 // 968 if(p.size == 0) 969 { 970 raxNode *n = raxNode.NewComp(cast(uint)s.length , false); 971 memcpy(n.str , s.ptr , s.length); 972 973 p = raxNode.RenewComp(p , 0 , true); 974 p.iskey = true; 975 p.value = data; 976 977 n.next = p; 978 head = n; 979 980 numnodes++; 981 982 log_info("####1"); 983 return 1; 984 } 985 else 986 { 987 988 // #2 直到匹配到叶子节点,都没有匹配到,必须往该叶子节点后面加剩余的字符。 989 // 'tester' 990 // ("test") --------> ("test") 991 // | | 992 // () ("er") 993 // | 994 // () 995 if(h.size == 0) 996 { 997 //1 new comp node 998 raxNode *n = raxNode.NewComp(last , true); 999 memcpy(n.str , s[ $ - last .. $].ptr , last); 1000 n.iskey = true; 1001 n.value = h.value; 1002 1003 h.value = data; 1004 1005 n.next = h; 1006 p.nextChild(index , n); 1007 1008 numnodes++; 1009 1010 log_info("####2"); 1011 return 1; 1012 } 1013 // #3 匹配到压缩节点,1 必须截断前部分。2 取原字符及压缩节点匹配字符构成 两个字符的 非压缩节点。 1014 // 3 非压缩节点 两个子节点 分别指向 截断后半部分 及 原字符后半部分 1015 // 1016 // 'teacher' 1017 // ('test')---------------->('te') 1018 // | | 1019 // (x) ['as'] u2 1020 // / \ 1021 // u4 ('cher') ('t') u3 1022 // / \ 1023 // u5 () (x) 1024 // 1025 else if(h.iscompr) { 1026 1027 raxNode *u1; 1028 1029 bool hasvalue = h.iskey && !h.isnull; 1030 auto u2 = raxNode.New(2 , hasvalue && splitpos <= 0); 1031 u2.str[0] = s[$ - last]; 1032 u2.str[1] = h.str[splitpos]; 1033 numnodes++; 1034 1035 1036 if( splitpos > 0) 1037 { 1038 u1 = raxNode.NewComp(splitpos , hasvalue); 1039 memcpy(u1.str , h.str , splitpos); 1040 u1.iskey = h.iskey; 1041 if(hasvalue) 1042 u1.value = h.value; 1043 numnodes++; 1044 } 1045 else{ 1046 u1 = u2; 1047 u1.iskey = h.iskey; 1048 if(hasvalue) 1049 u1.value = h.value; 1050 } 1051 1052 1053 uint u3_len = h.size - splitpos - 1; 1054 raxNode *u3; 1055 bool bcombine = false; 1056 if( u3_len > 0 ) 1057 { 1058 //combin 1059 if(h.next.size > 0 && h.next.iscompr && !h.next.iskey) 1060 { 1061 u3 = raxNode.NewComp(u3_len + h.next.size , h.next.iskey && !h.next.isnull); 1062 memcpy(u3.str , h.str + splitpos + 1 , h.size - splitpos -1); 1063 memcpy(u3.str + h.size - splitpos - 1 , h.next.str , h.next.size); 1064 numnodes++; 1065 bcombine = true; 1066 1067 } 1068 else 1069 { 1070 u3 = raxNode.NewComp(h.size - splitpos - 1 , false); 1071 memcpy(u3.str , h.str + splitpos + 1 ,h.size - splitpos -1); 1072 numnodes++; 1073 } 1074 } 1075 else 1076 { 1077 u3 = h.next; 1078 } 1079 1080 1081 //4 1082 uint u4_len = last - 1; 1083 raxNode *u4; 1084 1085 //5 1086 auto u5 = raxNode.NewComp(0 , true); 1087 u5.iskey = true; 1088 u5.value = data; 1089 numnodes++; 1090 1091 if(u4_len > 0) 1092 { 1093 u4 = raxNode.NewComp(last - 1, false); 1094 memcpy(u4.str , s.ptr + s.length - last + 1 , last - 1); 1095 numnodes++; 1096 } 1097 else{ 1098 u4 = u5; 1099 } 1100 1101 //relation 1102 if(u4_len > 0) 1103 u4.next = u5; 1104 1105 if(bcombine) 1106 { 1107 u3.next = h.next.next; 1108 raxNode.Free(h.next); 1109 numnodes--; 1110 } 1111 else if( u3_len > 0) 1112 { 1113 u3.next = h.next; 1114 } 1115 1116 u2.nextChild(0 , u4); 1117 u2.nextChild(1 , u3); 1118 1119 if(splitpos > 0) 1120 u1.next = u2; 1121 1122 p.nextChild(index , u1); 1123 1124 if( h == head) 1125 head = u1; 1126 1127 raxNode.Free(h); 1128 numnodes--; 1129 1130 log_info("####3"); 1131 return 1; 1132 1133 } 1134 // #4 都不匹配非压缩节点的任何子节点 1 增加该字符 2 截断原字符 1135 // 1136 // 'beer' 1137 // ["tes"] ---------> ['tesb'] 1138 // / / \ / / \ \ 1139 // () () () () () () ('eer') 1140 // \ 1141 // () 1142 else{ 1143 1144 bool hasdata = !h.isnull && h.iskey; 1145 auto i = raxNode.New( h.size + 1 , hasdata); 1146 i.iskey = h.iskey; 1147 if(hasdata) 1148 { 1149 i.value = h.value; //modify 1150 } 1151 1152 numnodes++; 1153 memcpy(i.str , h.str, h.size ); 1154 i.str[h.size] = s[$ - last]; 1155 memcpy(i.str + i.size , h.str + h.size , h.size * (raxNode *).sizeof); 1156 1157 1158 auto u1_len = last - 1; 1159 raxNode *u1; 1160 1161 1162 auto u2 = raxNode.NewComp(0 , true); 1163 u2.value = data; 1164 u2.iskey = true; 1165 numnodes++; 1166 if( u1_len > 0) 1167 { 1168 u1 = raxNode.NewComp(u1_len , false); 1169 memcpy(u1.str , s.ptr + s.length - last + 1 , u1_len); 1170 numnodes++; 1171 u1.next = u2; 1172 } 1173 else 1174 { 1175 u1 = u2; 1176 } 1177 1178 i.nextChild(h.size , u1); 1179 p.nextChild(index , i); 1180 1181 if(h == head) 1182 head = i; 1183 raxNode.Free(h); 1184 numnodes--; 1185 log_info("####4"); 1186 return 1; 1187 } 1188 } 1189 1190 }else{ 1191 // #5 完全匹配,只要改个值 即可。 1192 // 'te' 1193 // ('te') -------------> the same 1194 // | 1195 // ['as'] 1196 // / \ 1197 // ('cher') ('t') 1198 // | | 1199 // () () 1200 if(splitpos == 0) 1201 { 1202 bool hasdata = (h.iskey && !h.isnull); 1203 if(hasdata) { 1204 1205 h.value = data; 1206 if(h.iskey) //replaced 1207 numele--; 1208 else 1209 assert(0); 1210 1211 log_info("####50"); 1212 return 0; 1213 1214 } 1215 else{ 1216 raxNode *u; 1217 if(h.iscompr) 1218 u = raxNode.RenewComp(h , h.size , true); 1219 else 1220 { 1221 u = raxNode.Renew(h , h.size ,true); 1222 } 1223 u.value = data; 1224 u.iskey = true; 1225 p.nextChild(index , u); 1226 1227 log_info("####51"); 1228 return 1; 1229 } 1230 1231 1232 1233 } 1234 // #6 完全匹配压缩节点前半部分。 分割即可。 1235 // 'te' 1236 // ('test') ---------> ('te') 1237 // | | 1238 // (x) ('st') 1239 // | 1240 // (x) 1241 // 1242 else if(h.iscompr) { 1243 1244 1245 bool hasdata = (h.iskey && !h.isnull); 1246 auto u1 = raxNode.NewComp(splitpos , hasdata); 1247 memcpy(u1.str , h.str , splitpos); 1248 u1.iskey = h.iskey; 1249 if(hasdata) 1250 u1.value = h.value; 1251 numnodes++; 1252 1253 auto u2 = raxNode.NewComp(h.size - splitpos , true); 1254 memcpy(u2.str , h.str + splitpos , h.size - splitpos); 1255 u2.iskey = true; 1256 u2.value = data; 1257 numnodes++; 1258 u2.next = h.next; 1259 1260 1261 u1.next = u2; 1262 1263 raxNode.Free(h); 1264 numnodes--; 1265 if(h == head) 1266 { 1267 head = u1; 1268 } 1269 else{ 1270 p.nextChild(index , u1); 1271 } 1272 1273 log_info("####6"); 1274 return 1; 1275 }else{ 1276 writeln("assert"); 1277 assert(0); 1278 } 1279 } 1280 1281 } 1282 1283 // 1284 // api find 1285 // 1286 bool find(const ubyte[] s , out void *data) 1287 { 1288 raxNode *h = head; 1289 raxNode *p = head; 1290 raxItem [] ts; 1291 uint index = 0; 1292 uint splitpos = 0; 1293 uint last = find(s , h , p , index , splitpos , ts); 1294 if(last == 0 && splitpos == 0 && h.iskey) 1295 { 1296 data = h.value; 1297 return true; 1298 } 1299 1300 return false; 1301 } 1302 1303 private: 1304 1305 void RecursiveFree(raxNode *n) 1306 { 1307 int numchildren = 0; 1308 if(n.iscompr) 1309 { 1310 numchildren = n.size > 0 ? 1: 0; 1311 } 1312 else 1313 { 1314 numchildren = n.size; 1315 } 1316 while(numchildren--){ 1317 RecursiveFree(n.nextChild(numchildren)); 1318 } 1319 raxNode.Free(n); 1320 numnodes--; 1321 } 1322 1323 1324 //find 1325 uint find(const ubyte[] s , ref raxNode *r , ref raxNode *pr , ref uint index , ref uint splitpos ,ref raxItem[] ts) 1326 { 1327 //find it 1328 1329 if ( s is null) 1330 { 1331 return 0; 1332 } 1333 1334 if( r.size == 0) 1335 { 1336 return cast(uint)s.length; 1337 } 1338 1339 if ( r.iscompr ) //is compr 1340 { 1341 char *p = r.str; 1342 uint i = 0; 1343 for( i = 0 ; i < r.size && i < s.length ; i++) 1344 { 1345 if(p[i] != s[i]) 1346 break; 1347 } 1348 1349 1350 if( i == r.size) 1351 { 1352 pr = r; 1353 r = r.next; 1354 index = 0; 1355 raxItem item; 1356 item.n = pr; 1357 item.index = index; 1358 ts ~= item; 1359 return find(s[(*pr).size .. $] , r , pr, index , splitpos , ts); 1360 } 1361 else 1362 { 1363 splitpos = i; 1364 return cast(uint)s.length - i; 1365 } 1366 } 1367 else { 1368 1369 char *p = r.str; 1370 char *end = r.str + r.size; 1371 while(p != end) 1372 { 1373 if( *p == s[0]) 1374 break; 1375 p++; 1376 } 1377 1378 1379 uint i = cast(uint)(p - r.str); 1380 if( p == end) 1381 { 1382 splitpos = i; 1383 return cast(uint)s.length; 1384 } 1385 else 1386 { 1387 pr = r; 1388 index = i ; 1389 r = r.nextChild(index); 1390 raxItem item; 1391 item.n = pr; 1392 item.index = index; 1393 ts ~= item; 1394 return find(s[1 .. $] , r , pr , index , splitpos , ts); 1395 } 1396 } 1397 1398 } 1399 1400 string getStr(raxNode *h) 1401 { 1402 string str; 1403 for(uint i = 0 ; i < h.size ; i++) 1404 str ~= h.str[i]; 1405 return str; 1406 } 1407 1408 1409 void Recursiveshow(raxNode *n , int level) 1410 { 1411 1412 show(n , level); 1413 1414 if(n.size == 0) 1415 return ; 1416 1417 if(n.iscompr) 1418 { 1419 Recursiveshow(n.next , ++level); 1420 } 1421 else 1422 { 1423 ++level; 1424 for(uint i = 0 ; i < n.size ; i++) 1425 { 1426 Recursiveshow(n.nextChild(i) , level); 1427 } 1428 } 1429 } 1430 1431 void show(raxNode *n , int level) 1432 { 1433 1434 for(uint i = 0 ; i < level ; i++) 1435 write("\t"); 1436 write(" key:" , n.iskey , n.iscompr ? " (" : " ["); 1437 1438 for(uint i = 0 ; i < n.size ; i++) 1439 write(n.str[i]); 1440 1441 write(n.iscompr ? ") ":"] " , (n.iskey && !n.isnull)?n.value:null , "\n"); 1442 } 1443 1444 void show() 1445 { 1446 raxNode *p = head; 1447 writef("numele:%d numnodes:%d\n" , numele , numnodes); 1448 1449 1450 Recursiveshow(p ,0); 1451 1452 writef("\n"); 1453 } 1454 1455 1456 1457 1458 1459 }; 1460 1461 1462 1463 1464 1465 1466 1467 1468 unittest{ 1469 1470 1471 void test1() 1472 { 1473 string[] toadd = ["alligator","alien","baloon","chromodynamic","romane","romanus","romulus","rubens","ruber","rubicon","rubicundus","all","rub","ba"]; 1474 rax *r = rax.New(); 1475 foreach( i ,s ; toadd) 1476 { 1477 r.Insert(cast(ubyte[])s , cast(void *)i); 1478 } 1479 1480 foreach(s ; toadd) 1481 { 1482 r.Remove(cast(ubyte[])s); 1483 } 1484 r.show(); 1485 } 1486 1487 void test2() 1488 { 1489 string origin = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 1490 ~ "abcdefghijklmnopqrstuvwxyz" 1491 ~ "0123456789"; 1492 import std.random; 1493 1494 string[] keys; 1495 uint num = 1000; 1496 1497 for(uint j = 0 ; j < num ; j++) 1498 { 1499 uint len = uniform(1 , 16); 1500 string key; 1501 for(uint i = 0 ; i < len ; i++) 1502 { 1503 uint index = cast(uint) uniform(0 , origin.length); 1504 key ~= origin[index]; 1505 } 1506 keys ~= key; 1507 } 1508 1509 rax *r = rax.New(); 1510 foreach(i , k ; keys) 1511 { 1512 r.Insert(cast(ubyte[])k , cast(void *)i); 1513 } 1514 1515 1516 foreach(k ; keys) 1517 { 1518 r.Remove(cast(ubyte[])k); 1519 } 1520 1521 r.show(); 1522 assert(r.numele == 0); 1523 } 1524 1525 1526 } 1527 1528