added more methods to Dictionary.
made a simple optimization in dic.c
This commit is contained in:
parent
23d80e77aa
commit
6e335cd4fb
@ -127,7 +127,7 @@ class Set(Collection)
|
|||||||
method initialize
|
method initialize
|
||||||
{
|
{
|
||||||
self.tally := 0.
|
self.tally := 0.
|
||||||
self.bucket := Array new: 100.
|
self.bucket := Array new: 128. (* TODO: initial size *)
|
||||||
}
|
}
|
||||||
|
|
||||||
method size
|
method size
|
||||||
@ -135,28 +135,6 @@ class Set(Collection)
|
|||||||
^self.tally
|
^self.tally
|
||||||
}
|
}
|
||||||
|
|
||||||
method at: key
|
|
||||||
{
|
|
||||||
| ass |
|
|
||||||
ass := self __find: key or_upsert: false with: nil.
|
|
||||||
(ass notNil) ifTrue: [^ass value].
|
|
||||||
^ErrorCode.NOENT
|
|
||||||
}
|
|
||||||
|
|
||||||
method at: key ifAbsent: error_block
|
|
||||||
{
|
|
||||||
| ass |
|
|
||||||
ass := self __find: key or_upsert: false with: nil.
|
|
||||||
(ass notNil) ifTrue: [^ass value].
|
|
||||||
^error_block value.
|
|
||||||
}
|
|
||||||
|
|
||||||
method at: key put: value
|
|
||||||
{
|
|
||||||
self __find: key or_upsert: true with: value.
|
|
||||||
^value
|
|
||||||
}
|
|
||||||
|
|
||||||
method __find: key or_upsert: upsert with: value
|
method __find: key or_upsert: upsert with: value
|
||||||
{
|
{
|
||||||
| hv ass bs index ntally |
|
| hv ass bs index ntally |
|
||||||
@ -179,8 +157,23 @@ class Set(Collection)
|
|||||||
|
|
||||||
ntally := self.tally + 1.
|
ntally := self.tally + 1.
|
||||||
(ntally >= bs) ifTrue: [
|
(ntally >= bs) ifTrue: [
|
||||||
|
| newbuc newsz |
|
||||||
(* expand the bucket *)
|
(* expand the bucket *)
|
||||||
|
newsz := bs + 123. (* TODO: keep this growth policy in sync with VM(dic.c) *)
|
||||||
|
newbuc := Array new: newsz.
|
||||||
|
0 priorTo: bs do: [:i |
|
||||||
|
ass := self.bucket at: i.
|
||||||
|
(ass notNil) ifTrue: [
|
||||||
|
index := (ass key hash) rem: newsz.
|
||||||
|
[(newbuc at: index) notNil] whileTrue: [index := (index + 1) rem: newsz].
|
||||||
|
newbuc at: index put: ass
|
||||||
|
]
|
||||||
|
].
|
||||||
|
|
||||||
|
self.bucket := newbuc.
|
||||||
|
bs := self.bucket size.
|
||||||
|
index := hv rem: bs.
|
||||||
|
[(self.bucket at: index) notNil] whileTrue: [index := (index + 1) rem: bs ].
|
||||||
].
|
].
|
||||||
|
|
||||||
ass := Association key: key value: value.
|
ass := Association key: key value: value.
|
||||||
@ -190,6 +183,71 @@ class Set(Collection)
|
|||||||
^ass
|
^ass
|
||||||
}
|
}
|
||||||
|
|
||||||
|
method at: key
|
||||||
|
{
|
||||||
|
| ass |
|
||||||
|
ass := self __find: key or_upsert: false with: nil.
|
||||||
|
(ass notNil) ifTrue: [^ass value].
|
||||||
|
^ErrorCode.NOENT
|
||||||
|
}
|
||||||
|
|
||||||
|
method at: key ifAbsent: error_block
|
||||||
|
{
|
||||||
|
| ass |
|
||||||
|
ass := self __find: key or_upsert: false with: nil.
|
||||||
|
(ass notNil) ifTrue: [^ass value].
|
||||||
|
^error_block value.
|
||||||
|
}
|
||||||
|
|
||||||
|
method at: key put: value
|
||||||
|
{
|
||||||
|
self __find: key or_upsert: true with: value.
|
||||||
|
^value
|
||||||
|
}
|
||||||
|
|
||||||
|
method includesKey: key
|
||||||
|
{
|
||||||
|
| ass |
|
||||||
|
ass := self __find: key or_upsert: false with: nil.
|
||||||
|
^ass notNil
|
||||||
|
}
|
||||||
|
|
||||||
|
method includesAssociation: assoc
|
||||||
|
{
|
||||||
|
| ass |
|
||||||
|
ass := self __find: (assoc key) or_upsert: false with: nil.
|
||||||
|
^ass = assoc.
|
||||||
|
}
|
||||||
|
|
||||||
|
method includesKey: key value: value
|
||||||
|
{
|
||||||
|
| ass |
|
||||||
|
ass := self __find: key or_upsert: false with: nil.
|
||||||
|
^ass key = key and: [ass value = value]
|
||||||
|
}
|
||||||
|
|
||||||
|
method removeKey: key
|
||||||
|
{
|
||||||
|
(* TODO: *)
|
||||||
|
self subclassResponsbility: #removeKey
|
||||||
|
}
|
||||||
|
|
||||||
|
method removeKey: key ifAbsent: error_block
|
||||||
|
{
|
||||||
|
(* TODO: *)
|
||||||
|
self subclassResponsbility: #removeKey
|
||||||
|
}
|
||||||
|
|
||||||
|
method remove: assoc
|
||||||
|
{
|
||||||
|
^self removeKey: (assoc key)
|
||||||
|
}
|
||||||
|
|
||||||
|
method remove: assoc ifAbsent: error_block
|
||||||
|
{
|
||||||
|
^self removeKey: (assoc key) ifAbsent: error_block
|
||||||
|
}
|
||||||
|
|
||||||
method do: block
|
method do: block
|
||||||
{
|
{
|
||||||
| bs |
|
| bs |
|
||||||
@ -351,4 +409,4 @@ extend Apex
|
|||||||
{
|
{
|
||||||
^Association new key: self value: object
|
^Association new key: self value: object
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -10,11 +10,17 @@ class Association(Magnitude)
|
|||||||
{
|
{
|
||||||
^self new key: key value: value
|
^self new key: key value: value
|
||||||
}
|
}
|
||||||
|
|
||||||
method key: key value: value
|
method key: key value: value
|
||||||
{
|
{
|
||||||
self.key := key.
|
self.key := key.
|
||||||
self.value := value.
|
self.value := value.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
method value: value
|
||||||
|
{
|
||||||
|
self.value := value
|
||||||
|
}
|
||||||
|
|
||||||
method key
|
method key
|
||||||
{
|
{
|
||||||
|
@ -88,7 +88,7 @@ static stix_oop_oop_t expand_bucket (stix_t* stix, stix_oop_oop_t oldbuc)
|
|||||||
static stix_oop_association_t find_or_upsert (stix_t* stix, stix_oop_set_t dic, stix_oop_char_t key, stix_oop_t value)
|
static stix_oop_association_t find_or_upsert (stix_t* stix, stix_oop_set_t dic, stix_oop_char_t key, stix_oop_t value)
|
||||||
{
|
{
|
||||||
stix_ooi_t tally;
|
stix_ooi_t tally;
|
||||||
stix_oow_t index;
|
stix_oow_t hv, index;
|
||||||
stix_oop_association_t ass;
|
stix_oop_association_t ass;
|
||||||
stix_oow_t tmp_count = 0;
|
stix_oow_t tmp_count = 0;
|
||||||
|
|
||||||
@ -98,7 +98,8 @@ static stix_oop_association_t find_or_upsert (stix_t* stix, stix_oop_set_t dic,
|
|||||||
STIX_ASSERT (stix, STIX_CLASSOF(stix,dic->tally) == stix->_small_integer);
|
STIX_ASSERT (stix, STIX_CLASSOF(stix,dic->tally) == stix->_small_integer);
|
||||||
STIX_ASSERT (stix, STIX_CLASSOF(stix,dic->bucket) == stix->_array);
|
STIX_ASSERT (stix, STIX_CLASSOF(stix,dic->bucket) == stix->_array);
|
||||||
|
|
||||||
index = stix_hashoochars(key->slot, STIX_OBJ_GET_SIZE(key)) % STIX_OBJ_GET_SIZE(dic->bucket);
|
hv = stix_hashoochars(key->slot, STIX_OBJ_GET_SIZE(key));
|
||||||
|
index = hv % STIX_OBJ_GET_SIZE(dic->bucket);
|
||||||
|
|
||||||
/* find */
|
/* find */
|
||||||
while (dic->bucket->slot[index] != stix->_nil)
|
while (dic->bucket->slot[index] != stix->_nil)
|
||||||
@ -164,7 +165,7 @@ static stix_oop_association_t find_or_upsert (stix_t* stix, stix_oop_set_t dic,
|
|||||||
dic->bucket = bucket;
|
dic->bucket = bucket;
|
||||||
|
|
||||||
/* recalculate the index for the expanded bucket */
|
/* recalculate the index for the expanded bucket */
|
||||||
index = stix_hashoochars(key->slot, STIX_OBJ_GET_SIZE(key)) % STIX_OBJ_GET_SIZE(dic->bucket);
|
index = hv % STIX_OBJ_GET_SIZE(dic->bucket);
|
||||||
|
|
||||||
while (dic->bucket->slot[index] != stix->_nil)
|
while (dic->bucket->slot[index] != stix->_nil)
|
||||||
index = (index + 1) % STIX_OBJ_GET_SIZE(dic->bucket);
|
index = (index + 1) % STIX_OBJ_GET_SIZE(dic->bucket);
|
||||||
|
Loading…
Reference in New Issue
Block a user