diff options
author | Mike Buland <eichlan@xagasoft.com> | 2007-07-09 23:39:36 +0000 |
---|---|---|
committer | Mike Buland <eichlan@xagasoft.com> | 2007-07-09 23:39:36 +0000 |
commit | 316a5c83815a23d977785075c5dade4f6321ae09 (patch) | |
tree | 1b994fcf26b7e287b7f4f2909bbb3cf84955cd49 /src/fstring.h | |
parent | 34ea3c0a672760b93d5263f6e5bc9011dce2b186 (diff) | |
download | libbu++-316a5c83815a23d977785075c5dade4f6321ae09.tar.gz libbu++-316a5c83815a23d977785075c5dade4f6321ae09.tar.bz2 libbu++-316a5c83815a23d977785075c5dade4f6321ae09.tar.xz libbu++-316a5c83815a23d977785075c5dade4f6321ae09.zip |
Removed the refconuting for now, it just copies the string. Obviously it is
possible to make this much faster than I did, so I'll have to take another
crack at it later.
Diffstat (limited to '')
-rw-r--r-- | src/fstring.h | 173 |
1 files changed, 13 insertions, 160 deletions
diff --git a/src/fstring.h b/src/fstring.h index 65410af..be88ec0 100644 --- a/src/fstring.h +++ b/src/fstring.h | |||
@@ -49,7 +49,6 @@ namespace Bu | |||
49 | public: | 49 | public: |
50 | FBasicString() : | 50 | FBasicString() : |
51 | nLength( 0 ), | 51 | nLength( 0 ), |
52 | pnRefs( NULL ), | ||
53 | pFirst( NULL ), | 52 | pFirst( NULL ), |
54 | pLast( NULL ) | 53 | pLast( NULL ) |
55 | { | 54 | { |
@@ -57,7 +56,6 @@ namespace Bu | |||
57 | 56 | ||
58 | FBasicString( const chr *pData ) : | 57 | FBasicString( const chr *pData ) : |
59 | nLength( 0 ), | 58 | nLength( 0 ), |
60 | pnRefs( NULL ), | ||
61 | pFirst( NULL ), | 59 | pFirst( NULL ), |
62 | pLast( NULL ) | 60 | pLast( NULL ) |
63 | { | 61 | { |
@@ -66,7 +64,6 @@ namespace Bu | |||
66 | 64 | ||
67 | FBasicString( const chr *pData, long nLength ) : | 65 | FBasicString( const chr *pData, long nLength ) : |
68 | nLength( 0 ), | 66 | nLength( 0 ), |
69 | pnRefs( NULL ), | ||
70 | pFirst( NULL ), | 67 | pFirst( NULL ), |
71 | pLast( NULL ) | 68 | pLast( NULL ) |
72 | { | 69 | { |
@@ -75,21 +72,15 @@ namespace Bu | |||
75 | 72 | ||
76 | FBasicString( const MyType &rSrc ) : | 73 | FBasicString( const MyType &rSrc ) : |
77 | nLength( 0 ), | 74 | nLength( 0 ), |
78 | pnRefs( NULL ), | ||
79 | pFirst( NULL ), | 75 | pFirst( NULL ), |
80 | pLast( NULL ) | 76 | pLast( NULL ) |
81 | { | 77 | { |
82 | // Here we have no choice but to copy, since the other guy is a const. | 78 | rSrc.flatten(); |
83 | // In the case that the source were flat, we could get a reference, it | 79 | append( rSrc.pFirst->pData, rSrc.nLength ); |
84 | // would make some things faster, but not matter in many other cases. | ||
85 | |||
86 | joinShare( rSrc ); | ||
87 | //copyFrom( rSrc ); | ||
88 | } | 80 | } |
89 | 81 | ||
90 | FBasicString( const MyType &rSrc, long nLength ) : | 82 | FBasicString( const MyType &rSrc, long nLength ) : |
91 | nLength( 0 ), | 83 | nLength( 0 ), |
92 | pnRefs( NULL ), | ||
93 | pFirst( NULL ), | 84 | pFirst( NULL ), |
94 | pLast( NULL ) | 85 | pLast( NULL ) |
95 | { | 86 | { |
@@ -98,7 +89,6 @@ namespace Bu | |||
98 | 89 | ||
99 | FBasicString( const MyType &rSrc, long nStart, long nLength ) : | 90 | FBasicString( const MyType &rSrc, long nStart, long nLength ) : |
100 | nLength( 0 ), | 91 | nLength( 0 ), |
101 | pnRefs( NULL ), | ||
102 | pFirst( NULL ), | 92 | pFirst( NULL ), |
103 | pLast( NULL ) | 93 | pLast( NULL ) |
104 | { | 94 | { |
@@ -107,7 +97,6 @@ namespace Bu | |||
107 | 97 | ||
108 | FBasicString( long nSize ) : | 98 | FBasicString( long nSize ) : |
109 | nLength( nSize ), | 99 | nLength( nSize ), |
110 | pnRefs( NULL ), | ||
111 | pFirst( NULL ), | 100 | pFirst( NULL ), |
112 | pLast( NULL ) | 101 | pLast( NULL ) |
113 | { | 102 | { |
@@ -383,15 +372,7 @@ namespace Bu | |||
383 | */ | 372 | */ |
384 | MyType &operator =( const MyType &rSrc ) | 373 | MyType &operator =( const MyType &rSrc ) |
385 | { | 374 | { |
386 | //if( rSrc.isFlat() ) | 375 | copyFrom( rSrc ); |
387 | //{ | ||
388 | joinShare( rSrc ); | ||
389 | //} | ||
390 | //else | ||
391 | //{ | ||
392 | // copyFrom( rSrc ); | ||
393 | //} | ||
394 | // | ||
395 | 376 | ||
396 | return (*this); | 377 | return (*this); |
397 | } | 378 | } |
@@ -538,7 +519,6 @@ namespace Bu | |||
538 | void toLower() | 519 | void toLower() |
539 | { | 520 | { |
540 | flatten(); | 521 | flatten(); |
541 | unShare(); | ||
542 | 522 | ||
543 | for( long j = 0; j < nLength; j++ ) | 523 | for( long j = 0; j < nLength; j++ ) |
544 | { | 524 | { |
@@ -553,7 +533,6 @@ namespace Bu | |||
553 | void toUpper() | 533 | void toUpper() |
554 | { | 534 | { |
555 | flatten(); | 535 | flatten(); |
556 | unShare(); | ||
557 | 536 | ||
558 | for( long j = 0; j < nLength; j++ ) | 537 | for( long j = 0; j < nLength; j++ ) |
559 | { | 538 | { |
@@ -648,8 +627,6 @@ namespace Bu | |||
648 | if( pFirst == NULL ) | 627 | if( pFirst == NULL ) |
649 | return; | 628 | return; |
650 | 629 | ||
651 | unShare(); | ||
652 | |||
653 | Chunk *pNew = newChunk( nLength ); | 630 | Chunk *pNew = newChunk( nLength ); |
654 | chr *pos = pNew->pData; | 631 | chr *pos = pNew->pData; |
655 | Chunk *i = pFirst; | 632 | Chunk *i = pFirst; |
@@ -672,25 +649,18 @@ namespace Bu | |||
672 | if( pFirst == NULL ) | 649 | if( pFirst == NULL ) |
673 | return; | 650 | return; |
674 | 651 | ||
675 | if( isShared() ) | 652 | Chunk *i = pFirst; |
676 | { | 653 | for(;;) |
677 | decRefs(); | ||
678 | } | ||
679 | else | ||
680 | { | 654 | { |
681 | Chunk *i = pFirst; | 655 | Chunk *n = i->pNext; |
682 | for(;;) | 656 | aChr.deallocate( i->pData, i->nLength+1 ); |
683 | { | 657 | aChunk.deallocate( i, 1 ); |
684 | Chunk *n = i->pNext; | 658 | if( n == NULL ) |
685 | aChr.deallocate( i->pData, i->nLength+1 ); | 659 | break; |
686 | aChunk.deallocate( i, 1 ); | 660 | i = n; |
687 | if( n == NULL ) | ||
688 | break; | ||
689 | i = n; | ||
690 | } | ||
691 | pFirst = pLast = NULL; | ||
692 | nLength = 0; | ||
693 | } | 661 | } |
662 | pFirst = pLast = NULL; | ||
663 | nLength = 0; | ||
694 | } | 664 | } |
695 | 665 | ||
696 | void copyFrom( const FBasicString<chr, nMinSize, chralloc, chunkalloc> &rSrc ) | 666 | void copyFrom( const FBasicString<chr, nMinSize, chralloc, chunkalloc> &rSrc ) |
@@ -698,8 +668,6 @@ namespace Bu | |||
698 | if( rSrc.pFirst == NULL ) | 668 | if( rSrc.pFirst == NULL ) |
699 | return; | 669 | return; |
700 | 670 | ||
701 | decRefs(); | ||
702 | |||
703 | Chunk *pNew = newChunk( rSrc.nLength ); | 671 | Chunk *pNew = newChunk( rSrc.nLength ); |
704 | chr *pos = pNew->pData; | 672 | chr *pos = pNew->pData; |
705 | Chunk *i = rSrc.pFirst; | 673 | Chunk *i = rSrc.pFirst; |
@@ -721,11 +689,6 @@ namespace Bu | |||
721 | return (pFirst == pLast); | 689 | return (pFirst == pLast); |
722 | } | 690 | } |
723 | 691 | ||
724 | bool isShared() const | ||
725 | { | ||
726 | return (pnRefs != NULL); | ||
727 | } | ||
728 | |||
729 | Chunk *newChunk() const | 692 | Chunk *newChunk() const |
730 | { | 693 | { |
731 | Chunk *pNew = aChunk.allocate( 1 ); | 694 | Chunk *pNew = aChunk.allocate( 1 ); |
@@ -745,8 +708,6 @@ namespace Bu | |||
745 | 708 | ||
746 | void appendChunk( Chunk *pNewChunk ) | 709 | void appendChunk( Chunk *pNewChunk ) |
747 | { | 710 | { |
748 | unShare(); | ||
749 | |||
750 | if( pFirst == NULL ) | 711 | if( pFirst == NULL ) |
751 | pLast = pFirst = pNewChunk; | 712 | pLast = pFirst = pNewChunk; |
752 | else | 713 | else |
@@ -760,8 +721,6 @@ namespace Bu | |||
760 | 721 | ||
761 | void prependChunk( Chunk *pNewChunk ) | 722 | void prependChunk( Chunk *pNewChunk ) |
762 | { | 723 | { |
763 | unShare(); | ||
764 | |||
765 | if( pFirst == NULL ) | 724 | if( pFirst == NULL ) |
766 | pLast = pFirst = pNewChunk; | 725 | pLast = pFirst = pNewChunk; |
767 | else | 726 | else |
@@ -773,102 +732,6 @@ namespace Bu | |||
773 | nLength += pNewChunk->nLength; | 732 | nLength += pNewChunk->nLength; |
774 | } | 733 | } |
775 | 734 | ||
776 | void joinShare( MyType &rSrc ) | ||
777 | { | ||
778 | clear(); | ||
779 | |||
780 | if( !rSrc.isFlat() ) | ||
781 | rSrc.flatten(); | ||
782 | |||
783 | rSrc.initCount(); | ||
784 | pnRefs = rSrc.pnRefs; | ||
785 | (*pnRefs)++; | ||
786 | nLength = rSrc.nLength; | ||
787 | pFirst = rSrc.pFirst; | ||
788 | pLast = rSrc.pLast; | ||
789 | } | ||
790 | |||
791 | void joinShare( const MyType &rSrc ) | ||
792 | { | ||
793 | clear(); | ||
794 | |||
795 | rSrc.flatten(); | ||
796 | |||
797 | if( !rSrc.isShared() ) | ||
798 | { | ||
799 | rSrc.pnRefs = new uint32_t; | ||
800 | (*rSrc.pnRefs) = 1; | ||
801 | } | ||
802 | pnRefs = rSrc.pnRefs; | ||
803 | (*pnRefs)++; | ||
804 | nLength = rSrc.nLength; | ||
805 | pFirst = rSrc.pFirst; | ||
806 | pLast = rSrc.pLast; | ||
807 | } | ||
808 | |||
809 | /** | ||
810 | * This takes an object that was shared and makes a copy of the base data | ||
811 | * that was being shared so that this copy can be changed. This should be | ||
812 | * added before any call that will change this object; | ||
813 | */ | ||
814 | void unShare() const | ||
815 | { | ||
816 | if( isShared() == false ) | ||
817 | return; | ||
818 | if( pFirst == NULL ) | ||
819 | return; | ||
820 | |||
821 | Chunk *pNew = newChunk( nLength ); | ||
822 | chr *pos = pNew->pData; | ||
823 | Chunk *i = pFirst; | ||
824 | for(;;) | ||
825 | { | ||
826 | cpy( pos, i->pData, i->nLength ); | ||
827 | pos += i->nLength; | ||
828 | i = i->pNext; | ||
829 | if( i == NULL ) | ||
830 | break; | ||
831 | } | ||
832 | decRefs(); | ||
833 | pLast = pFirst = pNew; | ||
834 | nLength = pNew->nLength; | ||
835 | } | ||
836 | |||
837 | /** | ||
838 | * This decrements our ref count and pulls us out of the share. If the ref | ||
839 | * count hits zero because of this, it destroys the share. This is not | ||
840 | * safe to call on it's own, it's much better to call unShare. | ||
841 | */ | ||
842 | void decRefs() const | ||
843 | { | ||
844 | if( isShared() ) | ||
845 | { | ||
846 | (*pnRefs)--; | ||
847 | if( (*pnRefs) == 0 ) | ||
848 | destroyShare(); | ||
849 | else | ||
850 | { | ||
851 | pnRefs = NULL; | ||
852 | pFirst = NULL; | ||
853 | pLast = NULL; | ||
854 | nLength = 0; | ||
855 | } | ||
856 | } | ||
857 | } | ||
858 | |||
859 | /** | ||
860 | * While the unShare function removes an instance from a share, this | ||
861 | * function destroys the data that was in the share, removing the share | ||
862 | * itself. This should only be called when the refcount for the share has | ||
863 | * or is about to reach zero. | ||
864 | */ | ||
865 | void destroyShare() const | ||
866 | { | ||
867 | delete pnRefs; | ||
868 | pnRefs = NULL; | ||
869 | realClear(); | ||
870 | } | ||
871 | |||
872 | #ifdef VALTEST | 735 | #ifdef VALTEST |
873 | void cpy( chr *dest, const chr *src, long count ) const | 736 | void cpy( chr *dest, const chr *src, long count ) const |
874 | { | 737 | { |
@@ -881,18 +744,8 @@ namespace Bu | |||
881 | } | 744 | } |
882 | #endif | 745 | #endif |
883 | 746 | ||
884 | void initCount() const | ||
885 | { | ||
886 | if( !isShared() ) | ||
887 | { | ||
888 | pnRefs = new uint32_t; | ||
889 | (*pnRefs) = 1; | ||
890 | } | ||
891 | } | ||
892 | |||
893 | private: | 747 | private: |
894 | mutable long nLength; | 748 | mutable long nLength; |
895 | mutable uint32_t *pnRefs; | ||
896 | mutable Chunk *pFirst; | 749 | mutable Chunk *pFirst; |
897 | mutable Chunk *pLast; | 750 | mutable Chunk *pLast; |
898 | 751 | ||