implemented removal methods in the Set class

This commit is contained in:
hyunghwan.chung 2018-06-22 15:14:56 +00:00
parent b9500933b8
commit 7689de7dfa

View File

@ -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.