Levente Uzonyi uploaded a new version of Collections to project The Trunk:
http://source.squeak.org/trunk/Collections-ul.738.mcz
==================== Summary ====================
Name: Collections-ul.738
Author: ul
Time: 27 February 2017, 12:50:24.923499 am
UUID: 3cdaac93-5a62-4fb6-8037-4323767c63a1
Ancestors: Collections-ul.737
Part #3 of Improve SequenceableCollection's index-related search methods
- fixed typo in #indexOf:startingAt:ifAbsent:
- trimmed unnecessary #ifAbsent: sends
- improved a few methods
=============== Diff against Collections-ul.737 ===============
Item was changed:
----- Method: ByteString>>substrings (in category 'converting') -----
substrings
"Answer an array of the substrings that compose the receiver."
+
+ ^Array streamContents: [ :stream |
+ | end start |
+ end := 1.
+ "find one substring each time through this loop"
+ [ "find the beginning of the next substring"
+ (start := self
+ indexOfAnyOf: CharacterSet nonSeparators
+ startingAt: end) = 0 ]
+ whileFalse: [
+ "find the end"
+ end := self
+ indexOfAnyOf: CharacterSet separators
+ startingAt: start
+ ifAbsent: [ self size + 1 ].
+ stream nextPut: (self copyFrom: start to: end - 1) ] ]!
- | result end beginning |
- result := WriteStream on: (Array new: 10).
- end := 0.
- "find one substring each time through this loop"
- [ "find the beginning of the next substring"
- beginning := self indexOfAnyOf: CharacterSet nonSeparators
- startingAt: end+1 ifAbsent: [ nil ].
- beginning ~~ nil ] whileTrue: [
- "find the end"
- end := self indexOfAnyOf: CharacterSet separators
- startingAt: beginning ifAbsent: [ self size + 1 ].
- end := end - 1.
- result nextPut: (self copyFrom: beginning to: end).
- ].
- ^result contents!
Item was changed:
----- Method: RWBinaryOrTextStream>>upTo: (in category 'accessing') -----
upTo: anObject
"fast version using indexOf:"
| start end |
- start := position+1.
isBinary
ifTrue: [ anObject isInteger ifFalse: [ ^self upToEnd ] ]
ifFalse: [ anObject isCharacter ifFalse: [ ^self upToEnd ] ].
+ start := position + 1.
+ end := collection indexOf: anObject asCharacter startingAt: start.
- end := collection indexOf: anObject asCharacter startingAt: start ifAbsent: [ 0 ].
"not present--return rest of the collection"
(end = 0 or: [end > readLimit]) ifTrue: [ ^self upToEnd ].
"skip to the end and return the data passed over"
position := end.
^((isBinary ifTrue: [ ByteArray ] ifFalse: [ String ]) new: end - start)
replaceFrom: 1
to: end - start
with: collection
startingAt: start!
Item was changed:
----- Method: ReadStream>>upToAnyOf:do: (in category 'accessing') -----
upToAnyOf: aCollection do: aBlock
"Overriden for speed"
| end result |
+ end := collection indexOfAnyOf: aCollection startingAt: 1 + position.
- end := collection indexOfAnyOf: aCollection startingAt: 1 + position ifAbsent: [0].
(end = 0 or: [end > readLimit]) ifTrue: [^self upToEnd].
result := collection copyFrom: 1 + position to: -1 + end.
position := end.
aBlock value: (collection at: end).
^result!
Item was changed:
----- Method: SequenceableCollection>>indexOf:startingAt:ifAbsent: (in category 'accessing') -----
indexOf: anElement startingAt: start ifAbsent: exceptionBlock
"Answer the index of the first occurence of anElement after start
within the receiver. If the receiver does not contain anElement,
answer the result of evaluating the argument, exceptionBlock."
| index |
+ (index := self indexOf: anElement startingAt: start) = 0 ifFalse: [ ^index ].
- (index := self indexOf: start startingAt: start) = 0 ifFalse: [ ^index ].
^exceptionBlock value!
Item was changed:
----- Method: String>>withBlanksTrimmed (in category 'converting') -----
withBlanksTrimmed
"Return a copy of the receiver from which leading and trailing blanks have been trimmed."
| first last |
+ first := self indexOfAnyOf: CharacterSet nonSeparators startingAt: 1.
- first := self indexOfAnyOf: CharacterSet nonSeparators startingAt: 1 ifAbsent: [0].
first = 0 ifTrue: [ ^'' ]. "no non-separator character"
last := self lastIndexOfAnyOf: CharacterSet nonSeparators startingAt: self size ifAbsent: [self size].
(first = 1 and: [ last = self size ]) ifTrue: [ ^self copy ].
^self
copyFrom: first
to: last
!
Levente Uzonyi uploaded a new version of Collections to project The Trunk:
http://source.squeak.org/trunk/Collections-ul.736.mcz
==================== Summary ====================
Name: Collections-ul.736
Author: ul
Time: 26 February 2017, 9:40:39.679834 pm
UUID: 81b6c60e-5ac9-4fd9-a53e-ba9259958a1d
Ancestors: Collections-ul.735
Part #1 of Improve SequenceableCollection's index-related search methods
- moved actual implementations (in subclasses too) to block-free methods: #indexOf:startingAt:, #identityIndexOf:startingAt:, #indexOfAnyOf:startingAt:, #indexOfSubCollection:startingAt:, #lastIndexOf:startingAt: and #lastIndexOfAnyOf:startingAt:
- added #identityIndexOf:startingAt:, #identityIndexOf:startingAt:ifAbsent:, #lastIndexOfAnyOf:, #lastIndexOfAnyOf:ifAbsent:
- removed the now unnecessary #indexOf: override from ByteArray ans String
- pulled up #indexOfSubCollection: from String
- improved #replaceAll:with:
=============== Diff against Collections-ul.735 ===============
Item was removed:
- ----- Method: ByteArray>>indexOf: (in category 'accessing') -----
- indexOf: anInteger
-
- ^self indexOf: anInteger startingAt: 1!
Item was added:
+ ----- Method: Interval>>indexOf:startingAt: (in category 'accessing') -----
+ indexOf: anElement startingAt: startIndex
+ "startIndex is an positive integer, the collection index where the search is started."
+ "during the computation of val , floats are only used when the receiver contains floats"
+
+ | index val |
+ (self rangeIncludes: anElement) ifFalse: [ ^0 ].
+ val := anElement - self first / self increment.
+ val isFloat
+ ifTrue: [
+ (val - val rounded) abs * 100000000 < 1 ifFalse: [ ^0 ].
+ index := val rounded + 1 ]
+ ifFalse: [
+ val isInteger ifFalse: [ ^0 ].
+ index := val + 1 ].
+ "finally, the value of startIndex comes into play:"
+ (index between: startIndex and: self size) ifFalse: [ ^0 ].
+ ^index!
Item was added:
+ ----- Method: LinkedList>>indexOf:startingAt: (in category 'private') -----
+ indexOf: anElement startingAt: start
+ "Answer the index of the first occurence of anElement after start
+ within the receiver. If the receiver does not contain anElement,
+ answer the result of evaluating the argument, exceptionBlock."
+
+ |currentLink index|
+ currentLink := self linkAt: start ifAbsent: [nil].
+ index := start.
+ [ currentLink == nil ]
+ whileFalse: [currentLink value = anElement value ifTrue: [^index].
+ currentLink := currentLink nextLink.
+ index := index +1].
+ ^0!
Item was added:
+ ----- Method: OrderedCollection>>indexOf:startingAt: (in category 'accessing') -----
+ indexOf: anElement startingAt: start
+ "Optimized version."
+
+ firstIndex + start - 1 to: lastIndex do: [ :index |
+ (array at: index) = anElement ifTrue: [ ^index - firstIndex + 1 ] ].
+ ^0!
Item was changed:
----- Method: SequenceableCollection>>identityIndexOf: (in category 'accessing') -----
identityIndexOf: anElement
"Answer the index of anElement within the receiver. If the receiver does
not contain anElement, answer 0."
+ ^self identityIndexOf: anElement startingAt: 1!
- ^self identityIndexOf: anElement ifAbsent: [0]!
Item was changed:
----- Method: SequenceableCollection>>identityIndexOf:ifAbsent: (in category 'accessing') -----
identityIndexOf: anElement ifAbsent: exceptionBlock
"Answer the index of anElement within the receiver. If the receiver does
not contain anElement, answer the result of evaluating the argument,
exceptionBlock."
+
+ | index |
+ (index := self identityIndexOf: anElement startingAt: 1) = 0 ifFalse: [ ^index ].
+ ^exceptionBlock value!
- 1 to: self size do:
- [:i | (self at: i) == anElement ifTrue: [^ i]].
- ^ exceptionBlock value!
Item was added:
+ ----- Method: SequenceableCollection>>identityIndexOf:startingAt: (in category 'accessing') -----
+ identityIndexOf: anElement startingAt: startIndex
+ "Answer the index of anElement within the receiver starting at startIndex.
+ If the receiver does not contain anElement, answer 0."
+
+ startIndex to: self size do: [ :index |
+ (self at: index) == anElement ifTrue: [ ^index ] ].
+ ^0!
Item was added:
+ ----- Method: SequenceableCollection>>identityIndexOf:startingAt:ifAbsent: (in category 'accessing') -----
+ identityIndexOf: anElement startingAt: startIndex ifAbsent: exceptionBlock
+ "Answer the index of anElement within the receiver starting at startIndex.
+ If the receiver does not contain anElement, answer the result of evaluating
+ the argument, exceptionBlock."
+
+ | index |
+ (index := self identityIndexOf: anElement startingAt: 1) = 0 ifFalse: [ ^index ].
+ ^exceptionBlock value!
Item was changed:
----- Method: SequenceableCollection>>indexOf: (in category 'accessing') -----
indexOf: anElement
"Answer the index of the first occurence of anElement within the
receiver. If the receiver does not contain anElement, answer 0."
+ ^self indexOf: anElement startingAt: 1!
- ^ self indexOf: anElement ifAbsent: [0]!
Item was changed:
----- Method: SequenceableCollection>>indexOf:ifAbsent: (in category 'accessing') -----
indexOf: anElement ifAbsent: exceptionBlock
"Answer the index of the first occurence of anElement within the
receiver. If the receiver does not contain anElement, answer the
result of evaluating the argument, exceptionBlock."
+ | index |
+ (index := self indexOf: anElement startingAt: 1) = 0 ifFalse: [ ^index ].
+ ^exceptionBlock value!
- ^ self indexOf: anElement startingAt: 1 ifAbsent: exceptionBlock!
Item was changed:
----- Method: SequenceableCollection>>indexOf:startingAt: (in category 'accessing') -----
indexOf: anElement startingAt: start
"Answer the index of the first occurence of anElement after start
within the receiver. If the receiver does not contain anElement,
answer 0."
+ start to: self size do: [ :index |
+ (self at: index) = anElement ifTrue: [ ^index ] ].
+ ^0!
- ^self indexOf: anElement startingAt: start ifAbsent: 0!
Item was changed:
----- Method: SequenceableCollection>>indexOfAnyOf: (in category 'accessing') -----
indexOfAnyOf: aCollection
"Answer the index of the first occurence of any element included in aCollection within the receiver.
If the receiver does not contain anElement, answer zero, which is an invalid index."
+ ^self indexOfAnyOf: aCollection startingAt: 1!
- ^self indexOfAnyOf: aCollection startingAt: 1 ifAbsent: [0]!
Item was changed:
----- Method: SequenceableCollection>>indexOfAnyOf:startingAt: (in category 'accessing') -----
indexOfAnyOf: aCollection startingAt: start
"Answer the index of the first occurence of any element included in aCollection after start within the receiver.
If the receiver does not contain anElement, answer zero, which is an invalid index."
+ start to: self size do: [ :index |
+ (aCollection includes: (self at: index)) ifTrue: [ ^index ] ].
+ ^0!
- ^self indexOfAnyOf: aCollection startingAt: start ifAbsent: [0]!
Item was added:
+ ----- Method: SequenceableCollection>>indexOfSubCollection: (in category 'accessing') -----
+ indexOfSubCollection: aSubCollection
+ "Answer the index of the receiver's first element, such that that element
+ equals the first element of aSubCollection, and the next elements equal
+ the rest of the elements of aSubCollection. Begin the search at the first
+ element of the receiver. If no such match is found, answer 0."
+
+ ^self
+ indexOfSubCollection: aSubCollection
+ startingAt: 1!
Item was changed:
----- Method: SequenceableCollection>>indexOfSubCollection:startingAt: (in category 'accessing') -----
+ indexOfSubCollection: subCollection startingAt: start
- indexOfSubCollection: aSubCollection startingAt: anIndex
"Answer the index of the receiver's first element, such that that element
+ equals the first element of sub, and the next elements equal
+ the rest of the elements of sub. Begin the search at element
+ start of the receiver. If no such match is found, answer 0."
- equals the first element of aSubCollection, and the next elements equal
- the rest of the elements of aSubCollection. Begin the search at element
- anIndex of the receiver. If no such match is found, answer 0."
+ | first index subCollectionSize |
+ (subCollectionSize := subCollection size) = 0 ifTrue: [ ^0 ].
+ first := subCollection at: 1.
+ (start max: 1) to: self size - subCollectionSize + 1 do: [ :startIndex |
+ (self at: startIndex) = first ifTrue: [
+ index := 2.
+ [ index <= subCollectionSize
+ and: [ (self at: startIndex + index - 1) = (subCollection at: index) ] ]
+ whileTrue: [ index := index + 1 ].
+ index <= subCollectionSize ifFalse: [ ^startIndex ] ] ].
+ ^0!
- ^self
- indexOfSubCollection: aSubCollection
- startingAt: anIndex
- ifAbsent: [0]!
Item was changed:
----- Method: SequenceableCollection>>lastIndexOf: (in category 'accessing') -----
lastIndexOf: anElement
"Answer the index of the last occurence of anElement within the
receiver. If the receiver does not contain anElement, answer 0."
+ ^self lastIndexOf: anElement startingAt: self size!
- ^ self lastIndexOf: anElement startingAt: self size ifAbsent: [0]!
Item was changed:
----- Method: SequenceableCollection>>lastIndexOf:ifAbsent: (in category 'accessing') -----
lastIndexOf: anElement ifAbsent: exceptionBlock
"Answer the index of the last occurence of anElement within the
receiver. If the receiver does not contain anElement, answer the
result of evaluating the argument, exceptionBlock."
+
+ | index |
+ (index := self lastIndexOf: anElement startingAt: self size) = 0 ifFalse: [ ^index ].
+ ^exceptionBlock value!
- ^self lastIndexOf: anElement startingAt: self size ifAbsent: exceptionBlock!
Item was added:
+ ----- Method: SequenceableCollection>>lastIndexOf:startingAt: (in category 'accessing') -----
+ lastIndexOf: anElement startingAt: lastIndex
+ "Answer the index of the last occurence of anElement within the
+ receiver. If the receiver does not contain anElement, answer the
+ result of evaluating the argument, exceptionBlock."
+
+ lastIndex to: 1 by: -1 do: [ :index |
+ (self at: index) = anElement ifTrue: [ ^index ] ].
+ ^0!
Item was changed:
----- Method: SequenceableCollection>>lastIndexOf:startingAt:ifAbsent: (in category 'accessing') -----
lastIndexOf: anElement startingAt: lastIndex ifAbsent: exceptionBlock
"Answer the index of the last occurence of anElement within the
receiver. If the receiver does not contain anElement, answer the
result of evaluating the argument, exceptionBlock."
+ | index |
+ (index := self lastIndexOf: anElement startingAt: lastIndex) = 0 ifFalse: [ ^index ].
+ ^exceptionBlock value!
- lastIndex to: 1 by: -1 do:
- [:index |
- (self at: index) = anElement ifTrue: [^ index]].
- ^ exceptionBlock value!
Item was added:
+ ----- Method: SequenceableCollection>>lastIndexOfAnyOf: (in category 'accessing') -----
+ lastIndexOfAnyOf: aCollection
+ "Answer the index of the last occurence of any element of aCollection
+ within the receiver. If the receiver does not contain any of those
+ elements, answer 0"
+
+ ^self lastIndexOfAnyOf: aCollection startingAt: self size!
Item was added:
+ ----- Method: SequenceableCollection>>lastIndexOfAnyOf:ifAbsent: (in category 'accessing') -----
+ lastIndexOfAnyOf: aCollection ifAbsent: exceptionBlock
+ "Answer the index of the last occurence of any element of aCollection
+ within the receiver. If the receiver does not contain any of those
+ elements, answer the result of evaluating the argument, exceptionBlock."
+
+ | index |
+ (index := self lastIndexOfAnyOf: aCollection startingAt: self size) = 0 ifFalse: [ ^index ].
+ ^exceptionBlock value!
Item was added:
+ ----- Method: SequenceableCollection>>lastIndexOfAnyOf:startingAt: (in category 'accessing') -----
+ lastIndexOfAnyOf: aCollection startingAt: lastIndex
+ "Answer the index of the last occurence of any element of aCollection
+ within the receiver. If the receiver does not contain any of those
+ elements, answer 0"
+
+ lastIndex to: 1 by: -1 do: [ :index |
+ (aCollection includes: (self at: index)) ifTrue: [ ^index ] ].
+ ^0!
Item was changed:
----- Method: SequenceableCollection>>lastIndexOfAnyOf:startingAt:ifAbsent: (in category 'accessing') -----
lastIndexOfAnyOf: aCollection startingAt: lastIndex ifAbsent: exceptionBlock
+ "Answer the index of the last occurence of any element of aCollection
+ within the receiver. If the receiver does not contain any of those
+ elements, answer the result of evaluating the argument, exceptionBlock."
- "Answer the index of the last occurence of anElement within the
- receiver. If the receiver does not contain anElement, answer the
- result of evaluating the argument, exceptionBlock."
+ | index |
+ (index := self lastIndexOfAnyOf: aCollection startingAt: lastIndex) = 0 ifFalse: [ ^index ].
+ ^exceptionBlock value!
- lastIndex to: 1 by: -1 do:
- [:index |
- (aCollection includes: (self at: index)) ifTrue: [^ index]].
- ^ exceptionBlock value!
Item was changed:
----- Method: SequenceableCollection>>replaceAll:with: (in category 'accessing') -----
replaceAll: oldObject with: newObject
"Replace all occurences of oldObject with newObject"
+
| index |
+ index := 0.
+ [ (index := self indexOf: oldObject startingAt: index + 1) = 0 ]
+ whileFalse: [ self at: index put: newObject ]!
- index := self
- indexOf: oldObject
- startingAt: 1
- ifAbsent: [0].
- [index = 0]
- whileFalse:
- [self at: index put: newObject.
- index := self
- indexOf: oldObject
- startingAt: index + 1
- ifAbsent: [0]]!
Item was removed:
- ----- Method: String>>indexOf: (in category 'accessing') -----
- indexOf: aCharacter
-
- ^self indexOf: aCharacter startingAt: 1
- !
Item was removed:
- ----- Method: String>>indexOfSubCollection: (in category 'accessing') -----
- indexOfSubCollection: sub
- #Collectn.
- "Added 2000/04/08 For ANSI <sequenceReadableCollection> protocol."
- ^ self
- indexOfSubCollection: sub
- startingAt: 1
- ifAbsent: [0]!
Levente Uzonyi uploaded a new version of Collections to project The Trunk:
http://source.squeak.org/trunk/Collections-tonyg.733.1.mcz
==================== Summary ====================
Name: Collections-tonyg.733.1
Author: tonyg
Time: 23 February 2017, 2:44:28.751184 pm
UUID: e754e6ad-dd14-4e97-8ec1-82422b8feaa5
Ancestors: Collections-topa.733
Allow zero and negative startingAt indices in SequenceableCollection>>#indexOfSubCollection:startingAt:ifAbsent:, for compatibility with the existing implementation in String. Fixes tests in CollectionsTests-tonyg.275 and NetworkTests-tonyg.44.
=============== Diff against Collections-topa.733 ===============
Item was changed:
----- Method: SequenceableCollection>>indexOfSubCollection:startingAt:ifAbsent: (in category 'accessing') -----
indexOfSubCollection: sub startingAt: start ifAbsent: exceptionBlock
"Answer the index of the receiver's first element, such that that element
equals the first element of sub, and the next elements equal
the rest of the elements of sub. Begin the search at element
start of the receiver. If no such match is found, answer the result of
evaluating argument, exceptionBlock."
| first index |
sub isEmpty ifTrue: [^ exceptionBlock value].
first := sub first.
+ (start max: 1) to: self size - sub size + 1 do:
- start to: self size - sub size + 1 do:
[:startIndex |
(self at: startIndex) = first ifTrue:
[index := 1.
[(self at: startIndex+index-1) = (sub at: index)]
whileTrue:
[index = sub size ifTrue: [^startIndex].
index := index+1]]].
^ exceptionBlock value!
Levente Uzonyi uploaded a new version of Collections to project The Trunk:
http://source.squeak.org/trunk/Collections-ul.735.mcz
==================== Summary ====================
Name: Collections-ul.735
Author: ul
Time: 25 February 2017, 11:13:28.853237 pm
UUID: 69162a09-6a34-44b2-9a07-5a43e2020df6
Ancestors: Collections-eem.734, Collections-tonyg.733.1
- merged Collections-tonyg.733.1
- Character >> #isSeparator's old version's big comeback with improved comment and performance (25% faster on cog_linux64x64_squeak.cog.spur_201702211732).
=============== Diff against Collections-eem.734 ===============
Item was changed:
----- Method: Character>>isSeparator (in category 'testing') -----
isSeparator
"Answer whether the receiver is one of the separator characters--space,
cr, tab, line feed, or form feed."
| integerValue |
+ (integerValue := self asInteger) > 32 ifTrue: [ ^false ].
+ integerValue
+ caseOf: {
+ [ 32 "space" ] -> [ ^true ].
+ [ 9 "tab" ] -> [ ^true ].
+ [ 13 "cr"] -> [ ^true ].
+ [ 10 "line feed" ] -> [ ^true ].
+ [ 12 "form feed"] -> [ ^true ] }
+ otherwise: [ ^false ]!
- (integerValue := self asInteger) > 32 ifTrue: [^false].
- ^#(false false false false false false false false false
- true "9 = tab"
- true "10 = line feed"
- false
- true "12 = form feed"
- true "13 = cr"
- false false false false false false false false false false false false false false false false false false
- true) at: integerValue + 1!
Item was changed:
----- Method: SequenceableCollection>>indexOfSubCollection:startingAt:ifAbsent: (in category 'accessing') -----
indexOfSubCollection: sub startingAt: start ifAbsent: exceptionBlock
"Answer the index of the receiver's first element, such that that element
equals the first element of sub, and the next elements equal
the rest of the elements of sub. Begin the search at element
start of the receiver. If no such match is found, answer the result of
evaluating argument, exceptionBlock."
| first index |
sub isEmpty ifTrue: [^ exceptionBlock value].
first := sub first.
+ (start max: 1) to: self size - sub size + 1 do:
- start to: self size - sub size + 1 do:
[:startIndex |
(self at: startIndex) = first ifTrue:
[index := 1.
[(self at: startIndex+index-1) = (sub at: index)]
whileTrue:
[index = sub size ifTrue: [^startIndex].
index := index+1]]].
^ exceptionBlock value!
Eliot Miranda uploaded a new version of CollectionsTests to project The Trunk:
http://source.squeak.org/trunk/CollectionsTests-eem.275.mcz
==================== Summary ====================
Name: CollectionsTests-eem.275
Author: eem
Time: 25 February 2017, 11:33:14.19261 am
UUID: 4c41f0b5-8da9-4bdf-8a81-24f98cda5662
Ancestors: CollectionsTests-topa.274
Eliminating the explicit mapping to WideString in nextPut: fixes the testStreamAlwaysUseGivenCollection test.
=============== Diff against CollectionsTests-topa.274 ===============
Item was removed:
- ----- Method: WriteStreamTest>>expectedFailures (in category 'tests - character writing') -----
- expectedFailures
-
- ^ #( testStreamAlwaysUseGivenCollection )!