4 *new { arg n=2; ^super.new.initSet(max(n,2)*2) }
5 species { ^this.class }
6 copy { ^this.shallowCopy.array_( array.copy ) }
12 function.value(item, i);
19 clear { array.fill; size=0 }
20 makeEmpty { this.clear; }
23 ^array.at(this.scanFor(item)).notNil;
26 // return an item that matches a given item
27 ^array.at(this.scanFor(item));
31 if (item.isNil, { Error("A Set cannot contain nil.\n").throw; });
32 index = this.scanFor(item);
33 if ( array.at(index).isNil, { this.putCheck(index, item) });
36 var index = this.scanFor(item);
37 if ( array.at(index).notNil, {
38 array.put(index, nil);
40 this.fixCollisionsFrom(index);
45 if (size <= 0, { ^nil });
47 index = array.size.rand;
48 (val = array.at(index)).isNil;
55 (index < array.size) and: { (val = array.at(index)).isNil }
59 if (index < array.size, {
67 // ^this.asArray.sort.powerset
70 var result = this.species.new;
71 this.do {|x| result.addAll(x) }
75 var result = this.species.new;
77 if (that.includes(item), {
84 var result = this.species.new;
89 difference { arg that;
90 ^this.copy.removeAll(that);
92 symmetricDifference { arg that;
93 var result = this.species.new;
95 if (that.includes(item).not, {
100 if (this.includes(item).not, {
106 isSubsetOf { | that | ^that.includesAll(this) }
108 & { arg that; ^this.sect(that) }
109 | { arg that; ^this.union(that) }
110 - { arg that; ^this.difference(that) }
111 -- { arg that; ^this.symmetricDifference(that) }
114 // PRIVATE IMPLEMENTATION
115 initSet { arg n; array = Array.newClear(n); size = 0; }
116 putCheck { arg index, item;
117 array.put(index, item);
122 if (array.size < (size * 2), { this.grow });
125 var oldElements = array;
126 array = Array.newClear(array.size * 2);
128 oldElements.do({ arg item;
129 if ( item.notNil, { this.noCheckAdd(item) })
132 noCheckAdd { arg item;
133 array.put(this.scanFor(item), item);
138 var start = obj.hash % array.size;
139 var end = array.size;
142 while ({ i < end }, {
145 if ( elem.isNil or: { elem == obj }, { ^i });
150 while ({ i <= end }, {
152 if ( elem.isNil or: { elem == obj }, { ^i });
155 error("There is no free space in this set!\n");
160 fixCollisionsFrom { arg index;
161 var newIndex, element;
162 var oldIndex = index;
163 var lastKeyIndex = array.size - 1;
166 if (oldIndex == lastKeyIndex, { oldIndex = 0 }, { oldIndex = oldIndex + 1 });
167 (element = this.keyAt(oldIndex)).notNil
169 newIndex = this.scanFor(element);
170 if ( oldIndex != newIndex, { array.swap(oldIndex, newIndex) })
173 keyAt { arg index; ^array.at(index) }
179 scanFor { arg argKey;
180 ^array.atIdentityHash(argKey)
182 var i, start, end, elem;
184 start = obj.identityHash % array.size;
187 while ({ i < end }, {
189 if ( elem.isNil or: { elem === obj }, { ^i });
194 while ({ i < end }, {
196 if ( elem.isNil or: { elem === obj }, { ^i });
205 OrderedIdentitySet : IdentitySet {
210 .array_( array.copy )
211 .items_( items.copy )
233 putCheck { arg index, item;
234 super.putCheck(index, item);
235 items = items.add(item);