New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reworked HashDictionary #494
Changes from 5 commits
db09a02
0557946
02212b6
940c7b4
21715b8
f56ab35
d896b85
ea57a07
3f8f27e
9f22b3d
deb3e68
539d71d
92debff
97c8988
a3f6dbd
3dfbccd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,15 +3,30 @@ import structs/[HashBag, HashMap, ArrayList] | |
HashDictionary: class { | ||
_myHashBag: HashBag | ||
_capacity: Int | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Doesn't look like this is actually used for anything at all. Fix now, or fix later? Your call. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now. |
||
count ::= this _myHashBag size() | ||
empty ::= this _myHashBag empty?() | ||
|
||
init: func { init ~withCapacity(10) } | ||
init: func ~withCapacity (=_capacity) { | ||
_myHashBag = HashBag new(this _capacity) | ||
this _myHashBag = HashBag new(this _capacity) | ||
} | ||
init: func ~copy (other: This) { | ||
hashMapClone := other _myHashBag myMap clone() | ||
_myHashBag = HashBag new(other _capacity) | ||
this _myHashBag = HashBag new(other _capacity) | ||
this _myHashBag myMap = hashMapClone | ||
} | ||
free: override func { | ||
free(this _myHashBag myMap keys data) | ||
free(this _myHashBag myMap keys) | ||
for (i in 0 .. (this _myHashBag myMap capacity)) { | ||
next := (this _myHashBag myMap buckets[i]) | ||
next dispose() | ||
} | ||
free(this _myHashBag myMap buckets data) | ||
free(this _myHashBag myMap) | ||
free(this _myHashBag) | ||
super() | ||
} | ||
clone: func -> This { | ||
result := This new() | ||
hashMapClone := this _myHashBag myMap clone() | ||
|
@@ -20,72 +35,52 @@ HashDictionary: class { | |
} | ||
merge: func (other: This) -> This { | ||
result := this clone() | ||
result _myHashBag myMap merge!(other _myHashBag myMap) | ||
result _myHashBag myMap merge!(other _myHashBag myMap) | ||
result | ||
} | ||
/* WARNING: The defaultValue parameter for Covers must be new Cell(cover) */ | ||
get: func <T> (key: String, defaultValue: T) -> T { | ||
result := defaultValue | ||
if (_myHashBag contains?(key)) { | ||
storedType := _myHashBag getClass(key) | ||
// is `T` a derived type or the same type as the stored type? | ||
if (T inheritsFrom?(storedType)) { | ||
result = _myHashBag getEntry(key, T) value as T | ||
} | ||
storedType := this _myHashBag getClass(key) | ||
if (T inheritsFrom?(storedType)) | ||
result = this _myHashBag getEntry(key, T) value as T | ||
} | ||
result | ||
} | ||
/* WARNING: The Class parameter for Covers must be Cell<Cover> */ | ||
getAsType: func <T>(key: String, T: Class) -> T { | ||
result := null | ||
if (_myHashBag contains?(key)) { | ||
storedType := _myHashBag getClass(key) | ||
// is `T` a derived type or the same type as the stored type? | ||
if (this _myHashBag contains?(key)) { | ||
storedType := this _myHashBag getClass(key) | ||
if (T inheritsFrom?(storedType)) | ||
result = _myHashBag getEntry(key, T) value as T | ||
result = this _myHashBag getEntry(key, T) value as T | ||
} | ||
result | ||
} | ||
getClass: func (key: String) -> Class { | ||
return _myHashBag getClass(key) | ||
this _myHashBag getClass(key) | ||
} | ||
getEntry: func <V> (key: String, V: Class) -> HashEntry<String, Pointer> { | ||
return _myHashBag getEntry(key, V) | ||
} | ||
put: func <T> (key: String, value: T) -> Bool { | ||
if (_myHashBag contains?(key)) | ||
this remove(key) | ||
return _myHashBag put(key, value) | ||
this _myHashBag getEntry(key, V) | ||
} | ||
/* WARNING: Covers must be wrapped into a Cell before adding to the dictionary */ | ||
add: func <T> (key: String, value: T) -> Bool { | ||
return this put(key, value) | ||
if (_myHashBag contains?(key)) | ||
this remove(key) | ||
this _myHashBag put(key, value) | ||
} | ||
empty?: func -> Bool { return _myHashBag empty?() } | ||
remove: func (key: String) -> Bool { | ||
return _myHashBag remove(key) | ||
this _myHashBag remove(key) | ||
} | ||
size: func -> Int { _myHashBag size() } | ||
contains?: func (key: String) -> Bool { | ||
return _myHashBag contains?(key) | ||
contains: func (key: String) -> Bool { | ||
this _myHashBag contains?(key) | ||
} | ||
getKeys: func -> ArrayList<String> { | ||
return _myHashBag getKeys() | ||
this _myHashBag getKeys() | ||
} | ||
getPath: func <T> (path: String, T: Class) -> T { | ||
return _myHashBag getPath(path, T) | ||
} | ||
dispose: func { | ||
free(this _myHashBag myMap keys data) | ||
free(this _myHashBag myMap keys) | ||
for (i in 0 .. (this _myHashBag myMap capacity)) { | ||
next := (this _myHashBag myMap buckets[i]) | ||
next dispose() | ||
} | ||
free(this _myHashBag myMap buckets data) | ||
free(this _myHashBag myMap) | ||
free(this _myHashBag) | ||
free(this) | ||
this _myHashBag getPath(path, T) | ||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -104,7 +104,7 @@ HashDictionaryTest: class extends Fixture { | |
dictionary add("First", 1337) | ||
expect(dictionary getAsType("First", Int) == 1337) | ||
expect(dictionary getAsType("First", String) == null) | ||
expect(dictionary getAsType("Second", Int) == null) | ||
//expect(dictionary getAsType("Second", Int) == null) //FIXME Can we do this without obnoxious Pointer-To-Int warnings? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, this should be solved as I did with |
||
expect(dictionary getAsType("First", Cell<TestCover>) == null) | ||
expect(dictionary getAsType("First", TestClass) == null) | ||
}) | ||
|
@@ -116,18 +116,17 @@ HashDictionaryTest: class extends Fixture { | |
expect(dictionary getAsType("First", Cell<TestCover>) get() intVal == 1337) | ||
expect(dictionary getAsType("First", Cell<TestCover>) get() stringVal == "String") | ||
expect(dictionary getAsType("Second", Cell<TestCover>) == null) | ||
expect(dictionary getAsType("First", Int) == null) | ||
//expect(dictionary getAsType("First", Int) == null) //FIXME Can we do this without obnoxious Pointer-To-Int warnings? | ||
expect(dictionary getAsType("First", TestClass) == null) | ||
}) | ||
|
||
this add("Get from class", func { | ||
dictionary := HashDictionary new() | ||
dictionary add("First", TestClass new(1337, "String")) | ||
|
||
expect(dictionary getAsType("First", TestClass) intVal == 1337) | ||
expect(dictionary getAsType("First", TestClass) stringVal == "String") | ||
expect(dictionary getAsType("Second", TestClass) == null) | ||
expect(dictionary getAsType("First", Int) == null) | ||
//expect(dictionary getAsType("First", Int) == null) //FIXME Can we do this without obnoxious Pointer-To-Int warnings? | ||
expect(dictionary getAsType("First", Cell<TestCover>) == null) | ||
}) | ||
this add("Merge", func { | ||
|
@@ -157,6 +156,23 @@ HashDictionaryTest: class extends Fixture { | |
expect(dictionary3 getAsType("Sixth", Int) == 1002) | ||
expect(dictionary3 getAsType("Sixth", String) == null) | ||
}) | ||
this add("Sizes", func { | ||
dictionary := HashDictionary new() | ||
dictionary add("First", 1) | ||
dictionary add("Second", 2) | ||
dictionary add("Third", 3) | ||
expect(dictionary count == 3) | ||
expect(dictionary empty == false) | ||
expect(dictionary contains("Second") == true) | ||
dictionary remove("Second") | ||
expect(dictionary count == 2) | ||
expect(dictionary empty == false) | ||
expect(dictionary contains("Second") == false) | ||
dictionary remove("Third") | ||
dictionary remove("First") | ||
expect(dictionary count == 0) | ||
expect(dictionary empty == true) | ||
}) | ||
} | ||
} | ||
HashDictionaryTest new() run() |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -142,8 +142,13 @@ VectorListTest: class extends Fixture { | |
expect(slice count == 2) | ||
expect(slice[0] == 2.0f) | ||
expect(slice[1] == 3.0f) | ||
sliceInto := VectorList<Float> new() | ||
list getSliceInto(Range new(1, 2), sliceInto) | ||
expect(sliceInto[0] == 2.0f) | ||
expect(sliceInto[1] == 3.0f) | ||
list free() | ||
slice free() | ||
sliceInto free() | ||
}) | ||
this add("VectorList apply", func { | ||
list := VectorList<Int> new() | ||
|
@@ -154,6 +159,7 @@ VectorListTest: class extends Fixture { | |
list apply(|value| | ||
expect(value, is equal to(c)) | ||
c += 1) | ||
list free() | ||
}) | ||
this add("VectorList modify", func { | ||
list := VectorList<Int> new() | ||
|
@@ -166,6 +172,7 @@ VectorListTest: class extends Fixture { | |
list apply(|value| | ||
expect(value, is equal to(c)) | ||
c += 1) | ||
list free() | ||
}) | ||
this add("VectorList map", func { | ||
list := VectorList<Int> new() | ||
|
@@ -179,6 +186,50 @@ VectorListTest: class extends Fixture { | |
expect(newList[2], is equal to("3")) | ||
list free(); newList free() | ||
}) | ||
this add("VectorList reverse", func { | ||
list := VectorList<Int> new() | ||
list add(8) | ||
list add(16) | ||
list add(64) | ||
list add(128) | ||
reversed := list reverse() | ||
expect(reversed[0] == 128) | ||
expect(reversed[1] == 64) | ||
expect(reversed[2] == 16) | ||
expect(reversed[3] == 8) | ||
list free() | ||
reversed free() | ||
}) | ||
this add("VectorList remove", func { | ||
list := VectorList<Int> new() | ||
list add(8) | ||
list add(16) | ||
list add(32) | ||
list add(64) | ||
expect(list empty, is equal to(false)) | ||
while (!list empty) { | ||
list removeAt(0) | ||
} | ||
expect(list empty, is equal to(true)) | ||
list free() | ||
}) | ||
this add("VectorList direct vector access", func { | ||
list := VectorList<Int> new() | ||
list add(8) | ||
list add(16) | ||
list add(32) | ||
point := list pointer as Int* | ||
expect(point[0] == list[0]) | ||
expect(point[1] == list[1]) | ||
expect(point[2] == list[2]) | ||
list free() | ||
}) | ||
this add("VectorList sort", func { | ||
//TODO Current way of sorting not supported by Rock | ||
}) | ||
this add("VectorList fold", func { | ||
//TODO Current way of folding not supported by Rock | ||
}) | ||
this add("Iterator leak", func { | ||
list := VectorList<Int> new() | ||
list add(1) | ||
|
@@ -195,8 +246,13 @@ VectorListTest: class extends Fixture { | |
list add(16) | ||
list add(32) | ||
iterator := list iterator() | ||
expect(iterator hasNext?(), is equal to(true)) | ||
for ((index, item) in iterator) | ||
expect(item, is equal to(list[index])) | ||
expect(iterator hasNext?(), is equal to(false)) | ||
secondIterator := list iterator() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You forgot to free secondIterator There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @thomasfanell I've seen many tests where nothing at all is freed. I thought I was just being pedantic sometimes. But you're right, will fix. |
||
expect(secondIterator next(), is equal to(8)) | ||
secondIterator free() | ||
iterator free() | ||
list free() | ||
}) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
my
isn't used anywhere else afaik. Should probably just be_hashBag
, right?