'From Squeak3.2alpha of 2 October 2001 [latest update: #4434] on 16 October 2001 at 7:08:04 pm'! "Change Set: RunArrayTweaks-ar Date: 16 October 2001 Author: Andreas Raab Tweaks RunArrays by using Array instead of OrderedCollection for both, runs and values. In addition to a few other tweaks this speeds up #copyReplaceFrom:to:with: by roughly a factor of four, resulting in an average speedup of two for Text>>addAttribute:from:to: (this method does some stuff besides which I didn't touch)."! !SequenceableCollection methodsFor: 'copying' stamp: 'ar 10/16/2001 19:03'! copyReplaceFrom: start to: stop with: replacementCollection "Answer a copy of the receiver satisfying the following conditions: If stop is less than start, then this is an insertion; stop should be exactly start-1, start = 1 means insert before the first character, start = size+1 means append after last character. Otherwise, this is a replacement; start and stop have to be within the receiver's bounds." | newSequenceableCollection newSize endReplacement | newSize _ self size - (stop - start + 1) + replacementCollection size. endReplacement _ start - 1 + replacementCollection size. newSequenceableCollection _ self species new: newSize. start > 1 ifTrue:[ newSequenceableCollection replaceFrom: 1 to: start - 1 with: self startingAt: 1]. start <= endReplacement ifTrue:[ newSequenceableCollection replaceFrom: start to: endReplacement with: replacementCollection startingAt: 1]. endReplacement < newSize ifTrue:[ newSequenceableCollection replaceFrom: endReplacement + 1 to: newSize with: self startingAt: stop + 1]. ^newSequenceableCollection! ! !RunArray methodsFor: 'accessing' stamp: 'ar 10/16/2001 18:56'! first ^values at: 1! ! !RunArray methodsFor: 'accessing' stamp: 'ar 10/16/2001 18:56'! last ^values at: values size! ! !RunArray methodsFor: 'adding' stamp: 'ar 10/16/2001 18:47'! addFirst: value "Add value as the first element of the receiver." lastIndex _ nil. "flush access cache" (runs size=0 or: [values first ~= value]) ifTrue: [runs _ {1}, runs. values _ {value}, values] ifFalse: [runs at: 1 put: runs first+1]! ! !RunArray methodsFor: 'adding' stamp: 'ar 10/16/2001 18:46'! addLast: value "Add value as the last element of the receiver." lastIndex _ nil. "flush access cache" (runs size=0 or: [values last ~= value]) ifTrue: [runs _ runs copyWith: 1. values _ runs copyWith: value] ifFalse: [runs at: runs size put: runs last+1]! ! !RunArray methodsFor: 'adding' stamp: 'ar 10/16/2001 18:47'! addLast: value times: times "Add value as the last element of the receiver, the given number of times" times = 0 ifTrue: [ ^self ]. lastIndex _ nil. "flush access cache" (runs size=0 or: [values last ~= value]) ifTrue: [runs _ runs copyWith: times. values _ values copyWith: value] ifFalse: [runs at: runs size put: runs last+times]! ! !RunArray methodsFor: 'adding' stamp: 'ar 10/16/2001 18:48'! repeatLast: times ifEmpty: defaultBlock "add the last value back again, the given number of times. If we are empty, add (defaultBlock value)" times = 0 ifTrue: [^self ]. lastIndex _ nil. "flush access cache" (runs size=0) ifTrue: [runs _ runs copyWith: times. values _ values copyWith: defaultBlock value] ifFalse: [runs at: runs size put: runs last+times] ! ! !RunArray methodsFor: 'adding' stamp: 'ar 10/16/2001 18:48'! repeatLastIfEmpty: defaultBlock "add the last value back again. If we are empty, add (defaultBlock value)" lastIndex _ nil. "flush access cache" (runs size=0) ifTrue:[ runs _ runs copyWith: 1. values _ values copyWith: defaultBlock value] ifFalse: [runs at: runs size put: runs last+1]! ! !RunArray methodsFor: 'copying' stamp: 'ar 10/16/2001 18:57'! , aRunArray "Answer a new RunArray that is a concatenation of the receiver and aRunArray." | new newRuns | (aRunArray isMemberOf: RunArray) ifFalse: [new _ self copy. "attempt to be sociable" aRunArray do: [:each | new addLast: each]. ^new]. runs size = 0 ifTrue: [^aRunArray copy]. aRunArray runs size = 0 ifTrue: [^self copy]. (values at: values size) ~= (aRunArray values at: 1) ifTrue: [^RunArray runs: runs , aRunArray runs values: values , aRunArray values]. newRuns _ runs copyReplaceFrom: runs size to: runs size with: aRunArray runs. newRuns at: runs size put: (runs at: runs size) + (aRunArray runs at: 1). ^RunArray runs: newRuns values: (values copyReplaceFrom: values size to: values size with: aRunArray values)! ! !RunArray methodsFor: 'private' stamp: 'ar 10/16/2001 18:47'! setRuns: newRuns setValues: newValues lastIndex _ nil. "flush access cache" runs _ newRuns asArray. values _ newValues asArray.! ! !RunArray class methodsFor: 'instance creation' stamp: 'ar 10/16/2001 19:03'! new ^self runs: Array new values: Array new! ! !RunArray class methodsFor: 'instance creation' stamp: 'ar 10/16/2001 19:04'! new: size withAll: value "Answer a new instance of me, whose every element is equal to the argument, value." size = 0 ifTrue: [^self new]. ^self runs: (Array with: size) values: (Array with: value)! !