--- a/SegmentedOrderedCollection.st Wed Mar 20 00:39:10 2013 +0100
+++ b/SegmentedOrderedCollection.st Wed Mar 20 12:27:53 2013 +0100
@@ -11,15 +11,16 @@
documentation
"
- SegmentedOrderedCollections keep their elements in chunks (segments),
- allowing for relatively fast adding/removing at either end, AND inside the collection.
- For huge collections, performance is better for add/remove inside.
- Hoeverer, notice: when only removing at either end only, an OrderedCollection is much faster.
+ SegmentedOrderedCollections are intended as a replacement for huge OrderedCollections.
+ They keep their elements in chunks (segments), allowing for fast
+ adding/removing at either end AND relatively fast add/remove inside the collection.
+ For huge collections, the performance is much better when adding/removing inner elements.
+ However, notice: when only removing at either end only, an OrderedCollection is much faster.
- Usable for a replacement for OrderedCollections with big size (say > 10000),
- in which elements are going to be removed from the inside.
+ The break-even in performance depends on the number of elements and the usage pattern.
+ Consider it with (say) > 10000 elements and many adds/removes from the inside.
- Possibly unfinished (needs optimized search and replace).
+ Possibly unfinished (may need optimized search and replace).
[author:]
Claus Gittinger
@@ -35,6 +36,13 @@
"return an initialized instance"
^ self basicNew initialize.
+!
+
+new:size
+ "return an initialized instance with space for size elements.
+ However, be aware that the logical size is 0"
+
+ ^ self basicNew initialize.
! !
!SegmentedOrderedCollection methodsFor:'accessing'!
@@ -271,6 +279,46 @@
].
! !
+!SegmentedOrderedCollection methodsFor:'grow & shrink'!
+
+grow:newSize
+ "adjust the logical size to newSize"
+
+ |numExtraSegments segStart segEnd segIndex seg|
+
+ newSize == 0 ifTrue:[
+ segments := OrderedCollection new:2.
+ tally := 0.
+ ^ self
+ ].
+
+ newSize < tally ifTrue:[
+ "/ shrinking
+ segStart := 1.
+ segIndex := 1.
+ [true] whileTrue:[
+ seg := segments at:segIndex.
+ segEnd := segStart + (seg size - 1).
+ (newSize between:segStart and:segEnd) ifTrue:[
+ (segments at:segIndex) removeFromIndex:(newSize - segStart + 1 + 1).
+ segments removeFromIndex:segIndex+1.
+ tally := newSize.
+ ^ self
+ ].
+ segStart := segEnd + 1.
+ segIndex := segIndex + 1.
+ ].
+ "/ not reached
+ ].
+
+ "/ growing
+ numExtraSegments := (newSize - tally) // maxSegmentSize + 1.
+ numExtraSegments timesRepeat:[
+ segments add:((OrderedCollection new:maxSegmentSize) grow:maxSegmentSize)
+ ].
+ tally := newSize
+! !
+
!SegmentedOrderedCollection methodsFor:'initialization'!
initialize
@@ -290,10 +338,10 @@
!SegmentedOrderedCollection class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic2/SegmentedOrderedCollection.st,v 1.2 2013-03-19 11:53:31 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic2/SegmentedOrderedCollection.st,v 1.3 2013-03-20 11:27:53 cg Exp $'
!
version_CVS
- ^ '$Header: /cvs/stx/stx/libbasic2/SegmentedOrderedCollection.st,v 1.2 2013-03-19 11:53:31 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic2/SegmentedOrderedCollection.st,v 1.3 2013-03-20 11:27:53 cg Exp $'
! !