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