implemented removal methods in the Set class
This commit is contained in:
parent
b9500933b8
commit
7689de7dfa
@ -705,7 +705,7 @@ class Set(Collection)
|
|||||||
|
|
||||||
method initialize
|
method initialize
|
||||||
{
|
{
|
||||||
^self __initialize_with_size: 128. (* TODO: default initial size *)
|
^self __initialize_with_size: 1. (* TODO: default initial size *)
|
||||||
}
|
}
|
||||||
|
|
||||||
method __initialize_with_size: size
|
method __initialize_with_size: size
|
||||||
@ -720,7 +720,7 @@ class Set(Collection)
|
|||||||
| newbuc newsz ass index i |
|
| newbuc newsz ass index i |
|
||||||
|
|
||||||
(* expand the bucket *)
|
(* expand the bucket *)
|
||||||
newsz := bs + 128.
|
newsz := bs + 32. ## TODO: make this sizing operation configurable.
|
||||||
newbuc := Array new: newsz.
|
newbuc := Array new: newsz.
|
||||||
i := 0.
|
i := 0.
|
||||||
while (i < bs)
|
while (i < bs)
|
||||||
@ -738,7 +738,7 @@ class Set(Collection)
|
|||||||
^newbuc.
|
^newbuc.
|
||||||
}
|
}
|
||||||
|
|
||||||
method __find_index: anObject
|
method __find_index_for_add: anObject
|
||||||
{
|
{
|
||||||
| bs ass index |
|
| bs ass index |
|
||||||
|
|
||||||
@ -754,12 +754,65 @@ class Set(Collection)
|
|||||||
^index. ## the item at this index is nil.
|
^index. ## the item at this index is nil.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
method __find_index: anObject
|
||||||
|
{
|
||||||
|
| bs ass index |
|
||||||
|
|
||||||
|
bs := self.bucket size.
|
||||||
|
index := (anObject hash) rem: bs.
|
||||||
|
|
||||||
|
while ((ass := self.bucket at: index) notNil)
|
||||||
|
{
|
||||||
|
if (anObject = ass) { ^index }.
|
||||||
|
index := (index + 1) rem: bs.
|
||||||
|
}.
|
||||||
|
|
||||||
|
^Error.Code.ENOENT.
|
||||||
|
}
|
||||||
|
|
||||||
|
method __remove_at: index
|
||||||
|
{
|
||||||
|
| bs x y i v ass z |
|
||||||
|
|
||||||
|
bs := self.bucket size.
|
||||||
|
v := self.bucket at: index.
|
||||||
|
|
||||||
|
x := index.
|
||||||
|
y := index.
|
||||||
|
i := 0.
|
||||||
|
while (i < self.tally)
|
||||||
|
{
|
||||||
|
y := (y + 1) rem: bs.
|
||||||
|
|
||||||
|
ass := self.bucket at: y.
|
||||||
|
if (ass isNil) { (* done. the slot at the current index is nil *) break }.
|
||||||
|
|
||||||
|
(* get the natural hash index *)
|
||||||
|
z := (ass key hash) rem: bs.
|
||||||
|
|
||||||
|
(* move an element if necessary *)
|
||||||
|
if (((y > x) and ((z <= x) or (z > y))) or ((y < x) and ((z <= x) and (z > y))))
|
||||||
|
{
|
||||||
|
self.bucket at: x put: (self.bucket at: y).
|
||||||
|
x := y.
|
||||||
|
}.
|
||||||
|
|
||||||
|
i := i + 1.
|
||||||
|
}.
|
||||||
|
|
||||||
|
self.bucket at: x put: nil.
|
||||||
|
self.tally := self.tally - 1.
|
||||||
|
|
||||||
|
(* return the affected association *)
|
||||||
|
^v
|
||||||
|
}
|
||||||
|
|
||||||
method add: anObject
|
method add: anObject
|
||||||
{
|
{
|
||||||
| index absent bs |
|
| index absent bs |
|
||||||
if (anObject isNil) { ^anObject }.
|
if (anObject isNil) { ^anObject }.
|
||||||
|
|
||||||
index := self __find_index: anObject.
|
index := self __find_index_for_add: anObject.
|
||||||
absent := (self.bucket at: index) isNil.
|
absent := (self.bucket at: index) isNil.
|
||||||
self.bucket at: index put: anObject.
|
self.bucket at: index put: anObject.
|
||||||
|
|
||||||
@ -772,12 +825,25 @@ class Set(Collection)
|
|||||||
^anObject.
|
^anObject.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
method remove: oldObject
|
||||||
|
{
|
||||||
|
| index |
|
||||||
|
index := self __find_index: oldObject.
|
||||||
|
if (index isError) { ^NotFoundException signal. }.
|
||||||
|
^self __remove_at: index.
|
||||||
|
}
|
||||||
|
|
||||||
method remove: oldObject ifAbsent: anExceptionBlock
|
method remove: oldObject ifAbsent: anExceptionBlock
|
||||||
{
|
{
|
||||||
|
| index |
|
||||||
|
index := self __find_index: oldObject.
|
||||||
|
if (index isError) { ^anExceptionBlock value }.
|
||||||
|
^self __remove_at: index.
|
||||||
}
|
}
|
||||||
|
|
||||||
method includes: anObject
|
method includes: anObject
|
||||||
{
|
{
|
||||||
|
^(self __find_index: anObject) notError.
|
||||||
}
|
}
|
||||||
|
|
||||||
method isEmpty
|
method isEmpty
|
||||||
@ -785,6 +851,11 @@ class Set(Collection)
|
|||||||
^self.tally == 0
|
^self.tally == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
method size
|
||||||
|
{
|
||||||
|
^self.tally
|
||||||
|
}
|
||||||
|
|
||||||
method = aSet
|
method = aSet
|
||||||
{
|
{
|
||||||
ifnot (self class == aSet class) { ^false }.
|
ifnot (self class == aSet class) { ^false }.
|
||||||
@ -811,6 +882,7 @@ class AssociativeCollection(Collection)
|
|||||||
{
|
{
|
||||||
var tally, bucket.
|
var tally, bucket.
|
||||||
|
|
||||||
|
|
||||||
method(#class) new: size
|
method(#class) new: size
|
||||||
{
|
{
|
||||||
^self new __initialize_with_size: size.
|
^self new __initialize_with_size: size.
|
||||||
|
Loading…
Reference in New Issue
Block a user