[squeak-dev] The Trunk: Collections-ul.644.mcz

commits at source.squeak.org commits at source.squeak.org
Sat Aug 22 12:11:22 UTC 2015


Levente Uzonyi uploaded a new version of Collections to project The Trunk:
http://source.squeak.org/trunk/Collections-ul.644.mcz

==================== Summary ====================

Name: Collections-ul.644
Author: ul
Time: 22 August 2015, 2:50:48.28 am
UUID: 55f3957f-2ae4-4899-b3db-62dd7723d0f2
Ancestors: Collections-ul.643

Extracted and enhanced Bitset from WideCharacterSet.

=============== Diff against Collections-ul.643 ===============

Item was added:
+ Collection subclass: #Bitset
+ 	instanceVariableNames: 'bytes tally'
+ 	classVariableNames: ''
+ 	poolDictionaries: ''
+ 	category: 'Collections-Support'!
+ 
+ !Bitset commentStamp: 'ul 8/22/2015 00:52' prior: 0!
+ I implement Bitsets, which are dictionary-like data structures mapping 0-1 values to integers between 0 and capacity-1, or in another way they are set-like data structures which can include values between 0 and capacity-1.
+ I implement three different kind of APIs, each corresponding to a way of thinking about this data structure:
+ - A Set-like API with #add:, #remove: and #includes:
+ - A Dictionary-like API with #at:, #at:put:
+ - And a bit-manipulation API with #bitAt:, #clearBitAt: and #setBitAt:.
+ 
+ Instance Variables
+ 	bytes:		<ByteArray>
+ 	tally:		<Integer>
+ 
+ bytes
+ 	- a ByteArray which holds the values for each integer key. Each byte holds 8 values.
+ 
+ tally
+ 	- the number of objects in this set, or the number or 1 values in this dictionary.
+ !

Item was added:
+ ----- Method: Bitset class>>new (in category 'instance creation') -----
+ new
+ 
+ 	self error: 'Use #new: instead.'!

Item was added:
+ ----- Method: Bitset class>>new: (in category 'instance creation') -----
+ new: capacity
+ 
+ 	^self basicNew initialize: capacity!

Item was added:
+ ----- Method: Bitset>>= (in category 'comparing') -----
+ = anObject
+ 
+ 	self species == anObject species ifFalse: [ ^false ].
+ 	anObject size = tally ifFalse: [ ^false ].
+ 	^anObject bytes = bytes!

Item was added:
+ ----- Method: Bitset>>add: (in category 'adding') -----
+ add: anInteger
+ 	"Add anInteger to this set. Return anInteger."
+ 
+ 	self setBitAt: anInteger.
+ 	^anInteger!

Item was added:
+ ----- Method: Bitset>>at: (in category 'accessing') -----
+ at: anInteger
+ 
+ 	^self bitAt: anInteger
+ 		!

Item was added:
+ ----- Method: Bitset>>at:put: (in category 'accessing') -----
+ at: anInteger put: aBit
+ 
+ 	^self bitAt: anInteger put: aBit
+ 		!

Item was added:
+ ----- Method: Bitset>>bitAt: (in category 'bit manipulation') -----
+ bitAt: anInteger
+ 	"Return the bit corresponding to anInteger."
+ 
+ 	^((bytes at: (anInteger bitShift: -3) + 1) bitShift: 0 - (anInteger bitAnd: 7)) bitAnd: 1
+ 		!

Item was added:
+ ----- Method: Bitset>>bitAt:put: (in category 'bit manipulation') -----
+ bitAt: anInteger put: aBit
+ 	"Set the value corresponding to anInteger to aBit. Return the new value."
+ 
+ 	aBit caseOf: {
+ 		[ 0 ] -> [ self clearBitAt: anInteger ].
+ 		[ 1 ] -> [ self setBitAt: anInteger ] }.
+ 	^aBit
+ 		
+ 		!

Item was added:
+ ----- Method: Bitset>>bytes (in category 'private') -----
+ bytes
+ 
+ 	^bytes!

Item was added:
+ ----- Method: Bitset>>capacity (in category 'accessing') -----
+ capacity
+ 	"Return the highest integer this collection can store plus one."
+ 
+ 	^bytes size * 8!

Item was added:
+ ----- Method: Bitset>>clearBitAt: (in category 'bit manipulation') -----
+ clearBitAt: anInteger
+ 	"Set the value corresponding to anInteger to 0. Return true if the value wasn't 0."
+ 
+ 	| index value mask newValue |
+ 	index := (anInteger bitShift: -3) + 1.
+ 	value := bytes at: index.
+ 	mask := 1 bitShift: (anInteger bitAnd: 7).
+ 	(newValue := (value bitOr: mask) - mask) = value ifTrue: [ ^false ].
+ 	bytes at: index put: newValue.
+ 	tally := tally - 1.
+ 	^true
+ !

Item was added:
+ ----- Method: Bitset>>do: (in category 'enumerating') -----
+ do: aBlock
+ 	"Evaluate aBlock with each integer which has its bit set to 1."
+ 
+ 	| byte byteOffset lowBits remainingBits |
+ 	remainingBits := tally.
+ 	lowBits := Integer lowBitPerByteTable.
+ 	1 to: bytes size do: [ :index |
+ 		1 <= remainingBits ifFalse: [ ^self ].
+ 		(byte := bytes at: index) = 0 ifFalse: [
+ 			byteOffset := (index bitShift: 3) - 9. "- 8 - 1 to make it -1 based."
+ 			[
+ 				aBlock value: (lowBits at: byte) + byteOffset. "byteOffset is -1 based, lowBits is 1-based."
+ 				remainingBits := remainingBits - 1.
+ 				"Eliminate the low bit and loop if there're any remaning bits set."
+ 				(byte := byte bitAnd: byte - 1) = 0 ] whileFalse ] ]!

Item was added:
+ ----- Method: Bitset>>hash (in category 'comparing') -----
+ hash
+ 	"#hash is implemented, because #= is implemented."
+ 
+ 	^(self species hash bitXor: tally hashMultiply) bitXor: bytes hash!

Item was added:
+ ----- Method: Bitset>>includes: (in category 'testing') -----
+ includes: anInteger
+ 
+ 	anInteger isInteger ifFalse: [ ^false ].
+ 	-1 < anInteger ifFalse: [ ^false ].
+ 	anInteger < self capacity ifFalse: [ ^false ].
+ 	^(self bitAt: anInteger) = 1!

Item was added:
+ ----- Method: Bitset>>initialize: (in category 'private') -----
+ initialize: capacity
+ 	"Capacity is expected to be a non-negative, multiple-of-eight integer."
+ 
+ 	bytes := ByteArray new: capacity // 8.
+ 	tally := 0!

Item was added:
+ ----- Method: Bitset>>postCopy (in category 'copying') -----
+ postCopy
+ 	"Copy bytes as well."
+ 
+ 	bytes := bytes copy!

Item was added:
+ ----- Method: Bitset>>remove:ifAbsent: (in category 'removing') -----
+ remove: anInteger ifAbsent: absentBlock
+ 
+ 	(self clearBitAt: anInteger) ifTrue: [ ^anInteger ].
+ 	^absentBlock value!

Item was added:
+ ----- Method: Bitset>>removeAll (in category 'removing') -----
+ removeAll
+ 
+ 	tally = 0 ifTrue: [ ^self ].
+ 	bytes atAllPut: 0. "Unlike most #removeAll implementations, we don't allocate a new ByteArray here, because this is a bit more efficient. The VM would have to fill the new array with zeroes anyway."
+ 	tally := 0!

Item was added:
+ ----- Method: Bitset>>setBitAt: (in category 'bit manipulation') -----
+ setBitAt: anInteger
+ 	"Set the value corresponding to anInteger to 1. Return true if the value wasn't 1."
+ 
+ 	| index value newValue |
+ 	index := (anInteger bitShift: -3) + 1.
+ 	value := bytes at: index.
+ 	(newValue := (1 bitShift: (anInteger bitAnd: 7)) bitOr: value) = value ifTrue: [ ^false ].
+ 	bytes at: index put: newValue.
+ 	tally := tally + 1.
+ 	^true!

Item was added:
+ ----- Method: Bitset>>size (in category 'accessing') -----
+ size
+ 	"Return the number of 1 values in this collection."
+ 
+ 	^tally!



More information about the Squeak-dev mailing list