Set.st
branchjv
changeset 18011 deb0c3355881
parent 17966 8b5df02e171f
parent 14656 f5cab05e380f
child 18037 4cf874da38c9
equal deleted inserted replaced
18006:4e8f3d37bdbf 18011:deb0c3355881
    11 "
    11 "
    12 "{ Package: 'stx:libbasic' }"
    12 "{ Package: 'stx:libbasic' }"
    13 
    13 
    14 Collection subclass:#Set
    14 Collection subclass:#Set
    15 	instanceVariableNames:'tally keyArray'
    15 	instanceVariableNames:'tally keyArray'
    16 	classVariableNames:'DeletedEntry'
    16 	classVariableNames:'DeletedEntry NilEntry'
    17 	poolDictionaries:''
    17 	poolDictionaries:''
    18 	category:'Collections-Unordered'
    18 	category:'Collections-Unordered'
    19 !
    19 !
    20 
    20 
    21 Object subclass:#EmptySlot
    21 Object subclass:#EmptySlot
   567     ^ true.
   567     ^ true.
   568 
   568 
   569     "Modified: 30.1.1997 / 14:58:08 / cg"
   569     "Modified: 30.1.1997 / 14:58:08 / cg"
   570 ! !
   570 ! !
   571 
   571 
   572 !Set methodsFor:'binary storage'!
       
   573 
       
   574 readBinaryContentsFrom: stream manager: manager
       
   575     "must rehash after reload"
       
   576 
       
   577     super readBinaryContentsFrom: stream manager: manager.
       
   578     self rehash
       
   579 ! !
       
   580 
   572 
   581 !Set methodsFor:'comparing'!
   573 !Set methodsFor:'comparing'!
   582 
   574 
   583 = aCollection
   575 = aCollection
   584     "return true, if the argument is a Set containing the same elements
   576     "return true, if the argument is a Set containing the same elements
   585      as I do"
   577      as I do"
   586 
   578 
   587     aCollection species == self species ifFalse:[^ false].
   579     aCollection species ~~ self species ifTrue:[^ false].
   588     aCollection size == self size ifFalse:[^ false].
   580     aCollection size ~~ self size ifTrue:[^ false].
   589     "/ same number of elements; since I am a Set, all of
   581     "/ same number of elements; since I am a Set, all of
   590     "/ of my elements must be in the other collection ...
   582     "/ of my elements must be in the other collection ...
   591     ^ self conform:[:element | (aCollection includes:element)]
   583     self do:[:eachElement | (aCollection includes:eachElement) ifFalse:[^ false]].
       
   584     ^ true.
   592 
   585 
   593     "
   586     "
   594      #(1 2 3 4 5) asSet = #(2 3 4 5 1) asSet
   587      #(1 2 3 4 5) asSet = #(2 3 4 5 1) asSet
   595      #(nil 1 2 3 4 5) asSet = #(2 3 4 5 1) asSet´
   588      #(nil 1 2 3 4 5) asSet = #(2 3 4 5 1) asSet´
   596      #(1 2 3 4 5) asSet = #(2 3 4 5 1.0) asSet 
   589      #(1 2 3 4 5) asSet = #(2 3 4 5 1.0) asSet 
   646 
   639 
   647     "this hash is stupid - but for larger collections, the hashing
   640     "this hash is stupid - but for larger collections, the hashing
   648      time can become much bigger than the time lost in added probing.
   641      time can become much bigger than the time lost in added probing.
   649      Time will show ...
   642      Time will show ...
   650      Notice & warning:
   643      Notice & warning:
   651 	if the #= method is ever changed to compare non-dictionaries equal,
   644         if the #= method is ever changed to compare non-dictionaries equal,
   652 	the code below must be changed to assert that the same hash-value is 
   645         the code below must be changed to assert that the same hash-value is 
   653 	still returned.
   646         still returned.
   654 	(which may be hard to acomplish)
   647         (which may be hard to acomplish)
   655     "
   648     "
   656 
   649 
   657     |mySize|
   650     |mySize|
   658 
   651 
   659     mySize := self size.
   652     mySize := self size.
   660     mySize == 0 ifTrue:[^ 0].
   653     mySize == 0 ifTrue:[^ 0].
   661     ^ ((self first) hash times:mySize) bitAnd:16r3FFFFFFF
   654     ^ (self anElement hash times:mySize) bitAnd:16r3FFFFFFF
   662 
   655 
   663     "
   656     "
   664      |d|
   657      |d|
   665 
   658 
   666      d := Dictionary new.
   659      d := Dictionary new.
   679      d at:'one' put:1.
   672      d at:'one' put:1.
   680      d at:2 put:#two.
   673      d at:2 put:#two.
   681      d at:'two' put:2.
   674      d at:'two' put:2.
   682      d hash     
   675      d hash     
   683     "
   676     "
   684 
       
   685 
       
   686 
       
   687 
       
   688 ! !
   677 ! !
   689 
   678 
   690 !Set methodsFor:'copying'!
   679 !Set methodsFor:'copying'!
   691 
   680 
   692 postCopy
   681 postCopy
   718     ]
   707     ]
   719 
   708 
   720     "Modified: 1.3.1996 / 21:41:13 / cg"
   709     "Modified: 1.3.1996 / 21:41:13 / cg"
   721 ! !
   710 ! !
   722 
   711 
   723 !Set methodsFor:'inspecting'!
       
   724 
       
   725 inspectorClass
       
   726     "redefined to use SetInspector
       
   727      (instead of the default Inspector)."
       
   728 
       
   729     ^ SetInspectorView
       
   730 ! !
       
   731 
   712 
   732 !Set methodsFor:'obsolete set operations'!
   713 !Set methodsFor:'obsolete set operations'!
   733 
   714 
   734 + aCollection
   715 + aCollection
   735     "Kept for backward compatibility. 
   716     "Kept for backward compatibility. 
   834 !
   815 !
   835 
   816 
   836 findNil:key
   817 findNil:key
   837     "Look for the next slot usable for key.  
   818     "Look for the next slot usable for key.  
   838      WARNING:
   819      WARNING:
   839 	This method assumes that key is not already in the receiver 
   820         This method assumes that key is not already in the receiver 
   840 	AND that keyArray does not have previously removed entries 
   821         AND that keyArray does not have previously removed entries 
   841 	AND that there is an empty slot.
   822         AND that there is an empty slot.
   842      To be used ONLY while growing/rehashing to enter elements into a fresh
   823      To be used ONLY while growing/rehashing to enter elements into a fresh
   843      collection - if any of the above conditions is not met, the method
   824      collection - if any of the above conditions is not met, the method
   844      loops forever."
   825      loops forever."
   845 
   826 
   846     |index  "{ Class:SmallInteger }"
   827     |index  "{ Class:SmallInteger }"
   853 "/    index == 0 ifTrue:[
   834 "/    index == 0 ifTrue:[
   854 "/        index := keyArray identityIndexOf:nil startingAt:1 endingAt:index.
   835 "/        index := keyArray identityIndexOf:nil startingAt:1 endingAt:index.
   855 "/    ].
   836 "/    ].
   856     "/ that code is completely inlined by stc ...
   837     "/ that code is completely inlined by stc ...
   857     [(keyArray basicAt:index) notNil] whileTrue:[
   838     [(keyArray basicAt:index) notNil] whileTrue:[
   858 	index == length ifTrue:[
   839         index == length ifTrue:[
   859 	    index := 1
   840             index := 1
   860 	] ifFalse:[
   841         ] ifFalse:[
   861 	    index := index + 1
   842             index := index + 1
   862 	].
   843         ].
   863 	"notice: no check for no nil found - we must find one since
   844         "notice: no check for no nil found - we must find one since
   864 	 this is only called after growing"
   845          this is only called after growing"
   865     ].
   846     ].
   866     ^ index
   847     ^ index
   867 
   848 
   868     "Modified: 21.3.1997 / 10:32:58 / cg"
   849     "Modified: 21.3.1997 / 10:32:58 / cg"
   869 !
   850 !
   883     |index  "{ Class:SmallInteger }"
   864     |index  "{ Class:SmallInteger }"
   884      length "{ Class:SmallInteger }"|
   865      length "{ Class:SmallInteger }"|
   885 
   866 
   886     length := keyArray basicSize.
   867     length := keyArray basicSize.
   887     index := (self hashFor:aKey) bitAnd:16r3FFFFFFF.
   868     index := (self hashFor:aKey) bitAnd:16r3FFFFFFF.
   888     index < 16r1FFFFFFF ifTrue:[
   869 
   889 	index := index * 2
   870     "multiply by a large prime to spread the keys over the whole range.
   890     ].
   871      This causes maxChainLength to reduce from about 2000 to 6 for an
       
   872      IdentitySet of 9000 Smalltalk classes"
       
   873     index := index times:31415821.
   891     index := index \\ length + 1.
   874     index := index \\ length + 1.
   892     ^ index.
   875     ^ index.
       
   876 
       
   877     "
       
   878         Smalltalk allClasses maxChainLength
       
   879     "
   893 
   880 
   894     "Modified: 1.3.1997 / 01:01:13 / cg"
   881     "Modified: 1.3.1997 / 01:01:13 / cg"
   895     "Created: 19.3.1997 / 15:02:41 / cg"
   882     "Created: 19.3.1997 / 15:02:41 / cg"
   896 !
   883 !
   897 
   884 
  1083             count := count + (self collisionsFor:eachKey).
  1070             count := count + (self collisionsFor:eachKey).
  1084         ]
  1071         ]
  1085     ].
  1072     ].
  1086 
  1073 
  1087     ^ count
  1074     ^ count
       
  1075 
       
  1076     "
       
  1077       self allSubInstances 
       
  1078           collect:[:each| each collisionCount -> each] 
       
  1079           thenSelect:[:each| each key > 0]
       
  1080     "
  1088 !
  1081 !
  1089 
  1082 
  1090 collisionsFor:key
  1083 collisionsFor:key
  1091     "Return the number of searches - 1 required for key"
  1084     "Return the number of searches - 1 required for key"
  1092 
  1085 
  1093     |index  "{ Class:SmallInteger }"
  1086     |index  "{ Class:SmallInteger }"
  1094      length "{ Class:SmallInteger }"
  1087      length "{ Class:SmallInteger }" startIndex probe count|
  1095      hash "{ Class:SmallInteger }"
       
  1096      step "{ Class:SmallInteger }"
       
  1097      startIndex probe count|
       
  1098 
  1088 
  1099     length := keyArray basicSize.
  1089     length := keyArray basicSize.
  1100     hash := (self hashFor:key) bitAnd:16r3FFFFFFF.
  1090     startIndex := index := self initialIndexForKey:key.
  1101     hash < 16r1FFFFFFF ifTrue:[
       
  1102         hash := hash * 2
       
  1103     ].
       
  1104     startIndex := index := hash \\ length + 1.
       
  1105     step:= hash // length + 1.
       
  1106 
  1091 
  1107     count := 0.
  1092     count := 0.
  1108     [true] whileTrue:[
  1093     [true] whileTrue:[
  1109         probe := (keyArray basicAt:index).
  1094         probe := keyArray basicAt:index.
  1110         (probe notNil and:[key = probe]) ifTrue:[^ count].
  1095         (probe notNil and:[key = probe]) ifTrue:[^ count].
  1111         (self slotIsEmpty:probe) ifTrue:[self error:'non existing key'].
  1096         (self slotIsEmpty:probe) ifTrue:[self error:'non existing key'].
  1112 
  1097 
  1113         index == length ifTrue:[
  1098         index == length ifTrue:[
  1114             index := 1.
  1099             index := 1.
  1142     "return the number of set elements"
  1127     "return the number of set elements"
  1143 
  1128 
  1144     ^ tally
  1129     ^ tally
  1145 ! !
  1130 ! !
  1146 
  1131 
       
  1132 
  1147 !Set methodsFor:'testing'!
  1133 !Set methodsFor:'testing'!
  1148 
  1134 
  1149 capacity 
  1135 capacity 
  1150     "return the number of elements, that the receiver is
  1136     "return the number of elements, that the receiver is
  1151      prepared to take.
  1137      prepared to take.
  1243 ! !
  1229 ! !
  1244 
  1230 
  1245 !Set class methodsFor:'documentation'!
  1231 !Set class methodsFor:'documentation'!
  1246 
  1232 
  1247 version
  1233 version
  1248     ^ '$Header: /cvs/stx/stx/libbasic/Set.st,v 1.115 2012/08/13 17:11:21 stefan Exp $'
  1234     ^ '$Header: /cvs/stx/stx/libbasic/Set.st,v 1.117 2013-01-15 17:25:54 stefan Exp $'
  1249 !
  1235 !
  1250 
  1236 
  1251 version_CVS
  1237 version_CVS
  1252     ^ '§Header: /cvs/stx/stx/libbasic/Set.st,v 1.115 2012/08/13 17:11:21 stefan Exp §'
  1238     ^ '$Header: /cvs/stx/stx/libbasic/Set.st,v 1.117 2013-01-15 17:25:54 stefan Exp $'
  1253 !
  1239 ! !
  1254 
  1240 
  1255 version_SVN
       
  1256     ^ '$Id: Set.st 10844 2012-09-07 16:24:32Z vranyj1 $'
       
  1257 ! !
       
  1258 
  1241 
  1259 Set initialize!
  1242 Set initialize!