-
Notifications
You must be signed in to change notification settings - Fork 124
Perform immut/{set, sparse_array} #2272
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
base: main
Are you sure you want to change the base?
Conversation
Path comparison in Node::contains might cause infinite loopCategory (Branch(children), path) => {
if path.is_last() { return false }
let idx = path.idx()
if children[idx] is Some(child) {
continue (child, path.next())
}
false
} Reasoning Unnecessary allocations in union operationCategory fn go(node1, node2) {
match (node1, node2) {
(node, Flat(key, path)) | (Flat(key, path), node) =>
if node.contains(key, path) { node } else { node.add_with_path(key, path) } Reasoning Path implementation details are not well documentedCategory const SEGMENT_LENGTH : Int = 5 ///| A Path represents a sequence of 5-bit segments in a 32-bit integer.
/// The format is: HEAD_TAG | segment_n | ... | segment_1 | segment_0
/// where each segment is 5 bits and HEAD_TAG ensures the upper bits are set.
pub(all) type Path UInt derive(Eq) Reasoning |
Pull Request Test Coverage Report for Build 94Details
💛 - Coveralls |
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.
I'll leave it to the experts for the implementation of the algorithm, but here's something I've observed.
44df2f7
to
ad77ba3
Compare
btw from #2205 the optimized set operations seem quite independent, I think we should include that part in this PR too, so that there would be no performance degeneration in those operations |
3d148b8
to
1c87007
Compare
const SEGMENT_NUM : Int = 32 / SEGMENT_LENGTH | ||
|
||
///| | ||
const HEAD_TAG : UInt = 0xffffffffU << (SEGMENT_LENGTH * SEGMENT_NUM) |
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.
what's the purpose of this?
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.
So if I understand correctly, the new version only utilize the lower 30 bits of the hash value, and the highest 2 bits are used to identify end of hash value?
} | ||
} |
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.
just a note: maybe it's possible to also do path compression for Branch
(i.e. add an extra path segment (Path
+ length) parameter) too?
immut/hashset/HAMT.mbt
Outdated
(Collision(xs), Collision(ys)) => | ||
xs.size() == ys.size() && xs.iter().all(fn(x) { ys.find(x) }) | ||
(Leaf(x, xs), Leaf(y, ys)) => | ||
xs.length() == ys.length() && xs.add(x).iter().all(ys.add(y).contains(_)) |
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.
ys.add(y)
will be run multiple times here
04df5e1
to
558deab
Compare
558deab
to
ca818e3
Compare
(using arrow function) |
This PR is the first part of the split #2205, with clearer git history.
Path
to avoid passing depthCollision(Bucket[A])
withLeaf(A, @list.T[A])
T
toNode
, removeNode::empty
, defineT
asNode?
Branch({ data:[Branch(...)], .. })
byFlat(key, path)
Parts from #2205 not included in this PR:
add
/remove
to reuse old nodes in special cases (maybe we don't need this)union
,intersection
,difference
MyInt
, which only use the lower 8 bits for hashOverview