-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
[DEV] Implementation of Hash Table Data Structure #1627
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
Conversation
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.
Needs way more comments to properly explain a concept like hash tables.
codecov-commenter
commented
Mar 2, 2024
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@ ## master #1627 +/- ## ========================================== + Coverage 83.66% 83.88% +0.21% ========================================== Files 377 378 +1 Lines 19733 19841 +108 Branches 2907 2933 +26 ========================================== + Hits 16509 16643 +134 + Misses 3224 3198 -26 ☔ View full report in Codecov by Sentry. |
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.
Please remove unnecessary comments (prime example: // Initialize the hash variable to 0
is plain redundant with the code).
The tests are very barebones. Ideally you should roughly try to reach decent coverage. I'd like to see some tests for collisions, for example.
A simple way to reach decent coverage would be to execute more or less random operations, comparing the result against JS's Map
or a JS object.
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.
Use the #
syntax for private properties. The max
parameter is also unnecessary; you can just get it as this.storage.length
instead.
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 early return
here. Then you don't need the inserted
variable, and you will be more efficient (by not doing any further loop iterations).
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.
Use a for
-of
loop here: for (const entry of this.storage[index])
.
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.
It would be helpful to call this property this.#buckets
(it should also be private).
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.
This field is redundant with this.buckets.length
.
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.
100 seems very arbitrary. I'd force the user to choose for a fixed-size hash table. (I'd also make it clear that this is a fixed-size hash table (with dynamically grown buckets) as opposed to a dynamic hash table. In particular, a fixed-size hash table can't guarantee expected O(1) operations.)
limit
is also a slightly misleading name: This is not a hard limit, just a hash table "size". If you insert more elements, you will just get worse performance as your buckets fill up.
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'd use an early return here: const bucket = this.storage[index]; if (!bucket) return
(empty / undefined
bucket). Then you don't need to indent the rest of the function.
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.
(leaving an empty bucket behind wouldn't be an issue either; in fact i think the implementation may become slightly cleaner if you initialize all buckets to be empty, at a slight upfront performance cost at initialization)
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.
You're creating an array with holes here. I think this is rather dirty; it results in suboptimal time complexities (deleted items negatively affecting the time it takes to search a bucket).
It would be cleaner to just take an entry from the end, swap the entry to be deleted with that, then pop the entry from the end.
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 don't think "print" helpers are good design. A debugger, or even just JSON.stringify
, work just as well for inspecting values.
A better abstraction would be an "entries"-like method to iterate over all the key-value-pairs.
Open in Gitpod know more
Describe your change: