SegmentedOrderedCollection.st
changeset 2948 dc6efd25377b
parent 2935 d15b179aabfb
child 2949 bc40924d516b
--- 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 $'
 ! !