SegmentedOrderedCollection.st
author Claus Gittinger <cg@exept.de>
Wed, 20 Mar 2013 12:27:53 +0100
changeset 2948 dc6efd25377b
parent 2935 d15b179aabfb
child 2949 bc40924d516b
permissions -rw-r--r--
class: SegmentedOrderedCollection added: #grow:
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2916
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     1
"{ Package: 'stx:libbasic2' }"
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     2
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     3
SequenceableCollection subclass:#SegmentedOrderedCollection
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     4
	instanceVariableNames:'segments maxSegmentSize tally'
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     5
	classVariableNames:''
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     6
	poolDictionaries:''
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     7
	category:'Collections-Sequenceable'
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     8
!
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     9
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    10
!SegmentedOrderedCollection class methodsFor:'documentation'!
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    11
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    12
documentation
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    13
"
2948
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
    14
    SegmentedOrderedCollections are intended as a replacement for huge OrderedCollections.
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
    15
    They keep their elements in chunks (segments), allowing for fast 
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
    16
    adding/removing at either end AND relatively fast add/remove inside the collection.
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
    17
    For huge collections, the performance is much better when adding/removing inner elements.
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
    18
    However, notice: when only removing at either end only, an OrderedCollection is much faster.
2916
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    19
2948
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
    20
    The break-even in performance depends on the number of elements and the usage pattern.
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
    21
    Consider it with (say) > 10000 elements and many adds/removes from the inside.
2916
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    22
2948
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
    23
    Possibly unfinished (may need optimized search and replace).
2916
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    24
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    25
    [author:]
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    26
        Claus Gittinger
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    27
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    28
    [see also:]
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    29
        Array OrderedCollection BTree 
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    30
"
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    31
! !
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    32
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    33
!SegmentedOrderedCollection class methodsFor:'instance creation'!
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    34
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    35
new
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    36
    "return an initialized instance"
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    37
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    38
    ^ self basicNew initialize.
2948
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
    39
!
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
    40
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
    41
new:size
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
    42
    "return an initialized instance with space for size elements.
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
    43
     However, be aware that the logical size is 0"
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
    44
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
    45
    ^ self basicNew initialize.
2916
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    46
! !
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    47
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    48
!SegmentedOrderedCollection methodsFor:'accessing'!
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    49
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    50
at:index
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    51
    |segStart segEnd|
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    52
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    53
    (index between:1 and:tally) ifFalse:[
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    54
        ^ self indexNotIntegerOrOutOfBounds:index
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    55
    ].
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    56
    segStart := 1.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    57
    segments do:[:seg |
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    58
        segEnd := segStart + (seg size - 1).
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    59
        (index between:segStart and:segEnd) ifTrue:[
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    60
            ^ seg at:(index - segStart + 1).
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    61
        ].
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    62
        segStart := segEnd + 1.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    63
    ].
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    64
    self error:'oops - should not be here'
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    65
!
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    66
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    67
at:index put:newElement
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    68
    |segStart segEnd|
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    69
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    70
    (index between:1 and:tally) ifFalse:[
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    71
        ^ self indexNotIntegerOrOutOfBounds:index
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    72
    ].
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    73
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    74
    segStart := 1.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    75
    segments do:[:seg |
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    76
        segEnd := segStart + (seg size - 1).
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    77
        (index between:segStart and:segEnd) ifTrue:[
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    78
            ^ seg at:(index - segStart + 1) put:newElement.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    79
        ].
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    80
        segStart := segEnd + 1.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    81
    ].
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    82
    self error:'oops - should not be here'
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    83
!
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    84
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    85
first
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    86
    tally == 0 ifTrue:[^ self emptyCollectionError].
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    87
    ^ segments first first
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    88
!
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    89
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    90
last
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    91
    tally == 0 ifTrue:[^ self emptyCollectionError].
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    92
    ^ segments last last
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    93
! !
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    94
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    95
!SegmentedOrderedCollection methodsFor:'adding & removing'!
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    96
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    97
add:anObject
2935
d15b179aabfb class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2916
diff changeset
    98
    "add anObject to the end.
d15b179aabfb class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2916
diff changeset
    99
     Returns the object (sigh)"
2916
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   100
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   101
    |seg|
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   102
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   103
    (seg := segments last) size >= maxSegmentSize ifTrue:[
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   104
        self splitSegmentAt:(segments size).
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   105
        seg := segments last.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   106
    ].
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   107
    seg add:anObject.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   108
    tally := tally + 1.
2935
d15b179aabfb class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2916
diff changeset
   109
    ^ anObject.
d15b179aabfb class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2916
diff changeset
   110
!
d15b179aabfb class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2916
diff changeset
   111
d15b179aabfb class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2916
diff changeset
   112
add:anObject beforeIndex:index
d15b179aabfb class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2916
diff changeset
   113
    "insert the first argument, anObject into the collection before slot index.
d15b179aabfb class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2916
diff changeset
   114
     Return the receiver (sigh - ST-80 compatibility).
d15b179aabfb class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2916
diff changeset
   115
d15b179aabfb class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2916
diff changeset
   116
     Notice, that this is modifies the receiver NOT a copy."
d15b179aabfb class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2916
diff changeset
   117
d15b179aabfb class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2916
diff changeset
   118
    |prevSeg segStart|
d15b179aabfb class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2916
diff changeset
   119
d15b179aabfb class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2916
diff changeset
   120
    index == (tally+1) ifTrue:[
d15b179aabfb class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2916
diff changeset
   121
        ^ self add:anObject
d15b179aabfb class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2916
diff changeset
   122
    ].
d15b179aabfb class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2916
diff changeset
   123
    segStart := 1.
d15b179aabfb class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2916
diff changeset
   124
    segments do:[:seg |
d15b179aabfb class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2916
diff changeset
   125
        |segEnd|
d15b179aabfb class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2916
diff changeset
   126
d15b179aabfb class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2916
diff changeset
   127
        segEnd := segStart + (seg size - 1).
d15b179aabfb class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2916
diff changeset
   128
        (index between:segStart and:segEnd) ifTrue:[
d15b179aabfb class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2916
diff changeset
   129
            index == segStart ifTrue:[
d15b179aabfb class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2916
diff changeset
   130
                prevSeg notNil ifTrue:[
d15b179aabfb class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2916
diff changeset
   131
                    prevSeg size < seg size ifTrue:[
d15b179aabfb class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2916
diff changeset
   132
                        prevSeg add:anObject.
d15b179aabfb class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2916
diff changeset
   133
                        tally := tally + 1.
d15b179aabfb class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2916
diff changeset
   134
                        ^ anObject
d15b179aabfb class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2916
diff changeset
   135
                    ].
d15b179aabfb class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2916
diff changeset
   136
                ].
d15b179aabfb class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2916
diff changeset
   137
            ].
d15b179aabfb class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2916
diff changeset
   138
            seg add:anObject beforeIndex:(index - segStart + 1).
d15b179aabfb class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2916
diff changeset
   139
            tally := tally + 1.
d15b179aabfb class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2916
diff changeset
   140
            ^ anObject
d15b179aabfb class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2916
diff changeset
   141
        ].
d15b179aabfb class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2916
diff changeset
   142
        segStart := segEnd + 1.
d15b179aabfb class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2916
diff changeset
   143
        prevSeg := seg.
d15b179aabfb class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2916
diff changeset
   144
    ].
d15b179aabfb class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2916
diff changeset
   145
    self error:'oops - should not be here'
2916
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   146
!
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   147
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   148
addFirst:anObject
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   149
    "add anObject to the beginning (insert as new first element)."
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   150
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   151
    |seg|
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   152
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   153
    (seg := segments first) size >= maxSegmentSize ifTrue:[
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   154
        self splitSegmentAt:1.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   155
        seg := segments first.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   156
    ].
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   157
    seg addFirst:anObject.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   158
    tally := tally + 1.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   159
!
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   160
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   161
removeFirst
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   162
    |seg el|
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   163
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   164
    tally == 0 ifTrue:[
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   165
        ^ self emptyCollectionError
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   166
    ].
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   167
    seg := segments first.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   168
    el := seg removeFirst.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   169
    seg isEmpty ifTrue:[
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   170
        segments removeFirst
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   171
    ].
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   172
    tally := tally - 1.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   173
    ^ el
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   174
!
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   175
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   176
removeFromIndex:startIndex toIndex:endIndex
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   177
    |segStart segEnd removing segIndex nextSegIndex seg|
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   178
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   179
    (startIndex between:1 and:tally) ifFalse:[
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   180
        ^ self indexNotIntegerOrOutOfBounds:startIndex
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   181
    ].
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   182
    (endIndex between:1 and:tally) ifFalse:[
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   183
        ^ self indexNotIntegerOrOutOfBounds:endIndex
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   184
    ].
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   185
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   186
    segStart := 1.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   187
    segIndex := 1.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   188
    removing := false.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   189
    [true] whileTrue:[
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   190
        seg := segments at:segIndex.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   191
        nextSegIndex := segIndex + 1.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   192
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   193
        segEnd := segStart + (seg size - 1).
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   194
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   195
        removing ifFalse:[
2935
d15b179aabfb class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2916
diff changeset
   196
            "still searching for the segment"
2916
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   197
            (startIndex between:segStart and:segEnd) ifTrue:[
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   198
                (endIndex between:segStart and:segEnd) ifTrue:[
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   199
                    seg removeFromIndex:(startIndex - segStart + 1) toIndex:(endIndex - segStart + 1).
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   200
                    seg isEmpty ifTrue:[
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   201
                        segments removeAtIndex:segIndex.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   202
                    ].
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   203
                    tally := tally - (endIndex - startIndex + 1).
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   204
                    ^ self.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   205
                ].
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   206
                seg removeFromIndex:(startIndex - segStart + 1).        
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   207
                seg isEmpty ifTrue:[
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   208
                    segments removeAtIndex:segIndex.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   209
                    nextSegIndex := segIndex.    
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   210
                ].
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   211
                removing := true.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   212
            ].
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   213
        ] ifTrue:[
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   214
            (endIndex between:segStart and:segEnd) ifTrue:[
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   215
                seg removeFromIndex:1 toIndex:(endIndex - segStart + 1).
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   216
                seg isEmpty ifTrue:[
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   217
                    segments removeAtIndex:segIndex.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   218
                ].
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   219
                tally := tally - (endIndex - startIndex + 1).
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   220
                ^ self.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   221
            ] ifFalse:[
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   222
                "/ remove the whole segment
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   223
                segments removeAtIndex:segIndex.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   224
                nextSegIndex := segIndex.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   225
            ]
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   226
        ].
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   227
        segStart := segEnd + 1.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   228
        segIndex := nextSegIndex.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   229
    ].
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   230
    self halt:'should not be here'
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   231
!
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   232
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   233
removeLast
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   234
    |seg el|
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   235
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   236
    tally == 0 ifTrue:[
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   237
        ^ self emptyCollectionError
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   238
    ].
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   239
    seg := segments last.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   240
    el := seg removeLast.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   241
    seg isEmpty ifTrue:[
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   242
        segments removeLast
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   243
    ].
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   244
    tally := tally - 1.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   245
    ^ el
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   246
!
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   247
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   248
splitSegmentAt:segmentIndex
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   249
    |seg rightPart|
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   250
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   251
    seg := segments at:segmentIndex.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   252
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   253
    rightPart := OrderedCollection new:20.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   254
    rightPart grow:10.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   255
    rightPart replaceFrom:1 to:10 with:seg startingAt:(seg size - 9).
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   256
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   257
    seg removeFromIndex:(seg size - 9) toIndex:seg size.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   258
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   259
    segments add:rightPart afterIndex:segmentIndex.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   260
! !
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   261
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   262
!SegmentedOrderedCollection methodsFor:'enumerating'!
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   263
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   264
do:aBlock
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   265
    segments do:[:seg |
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   266
        seg do:aBlock
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   267
    ].
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   268
!
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   269
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   270
keysAndValuesDo:aBlock
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   271
    |idx|
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   272
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   273
    idx := 1.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   274
    segments do:[:seg |
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   275
        seg do:[:each |
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   276
            aBlock value:idx value:each.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   277
            idx := idx + 1.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   278
        ]
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   279
    ].
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   280
! !
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   281
2948
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   282
!SegmentedOrderedCollection methodsFor:'grow & shrink'!
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   283
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   284
grow:newSize
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   285
    "adjust the logical size to newSize"
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   286
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   287
    |numExtraSegments segStart segEnd segIndex seg|
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   288
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   289
    newSize == 0 ifTrue:[
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   290
        segments := OrderedCollection new:2.
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   291
        tally := 0.
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   292
        ^ self
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   293
    ].
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   294
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   295
    newSize < tally ifTrue:[
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   296
        "/ shrinking
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   297
        segStart := 1.
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   298
        segIndex := 1.
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   299
        [true] whileTrue:[
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   300
            seg := segments at:segIndex.
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   301
            segEnd := segStart + (seg size - 1).
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   302
            (newSize between:segStart and:segEnd) ifTrue:[
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   303
                (segments at:segIndex) removeFromIndex:(newSize - segStart + 1 + 1).
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   304
                segments removeFromIndex:segIndex+1.
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   305
                tally := newSize.
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   306
                ^ self
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   307
            ].
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   308
            segStart := segEnd + 1.
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   309
            segIndex := segIndex + 1.
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   310
        ].
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   311
        "/ not reached
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   312
    ].
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   313
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   314
    "/ growing
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   315
    numExtraSegments := (newSize - tally) // maxSegmentSize + 1.
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   316
    numExtraSegments timesRepeat:[
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   317
        segments add:((OrderedCollection new:maxSegmentSize) grow:maxSegmentSize)
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   318
    ].
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   319
    tally := newSize
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   320
! !
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   321
2916
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   322
!SegmentedOrderedCollection methodsFor:'initialization'!
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   323
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   324
initialize
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   325
    "Invoked when a new instance is created."
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   326
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   327
    segments := OrderedCollection with:(OrderedCollection new:10).
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   328
    maxSegmentSize := 200.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   329
    tally := 0.
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   330
! !
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   331
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   332
!SegmentedOrderedCollection methodsFor:'queries'!
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   333
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   334
size
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   335
    ^ tally
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   336
! !
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   337
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   338
!SegmentedOrderedCollection class methodsFor:'documentation'!
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   339
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   340
version
2948
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   341
    ^ '$Header: /cvs/stx/stx/libbasic2/SegmentedOrderedCollection.st,v 1.3 2013-03-20 11:27:53 cg Exp $'
2916
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   342
!
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   343
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   344
version_CVS
2948
dc6efd25377b class: SegmentedOrderedCollection
Claus Gittinger <cg@exept.de>
parents: 2935
diff changeset
   345
    ^ '$Header: /cvs/stx/stx/libbasic2/SegmentedOrderedCollection.st,v 1.3 2013-03-20 11:27:53 cg Exp $'
2916
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   346
! !
984324441864 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   347