Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Fix double free bug, some interface redesign (#10) * fix double free, change insert_or_modify interface fixing the double free was surprisingly subtle, and involved a few small changes to the algorithm to bring it more in line with Cliff Click's 2007 lockfree hash table. first, it is no longer possible for multiple rehashing operations to be in flight at once. this is primarily for simplicity's sake, but Click claims it's faster this way. next, bucket pointers that have been copied from an old table are marked with a tag bit. this prevents writes on the old table from overwriting writes on the new table. finally, removal and no longer requires the key to be cloned. instead, the value is destroyed via MaybeUninit shenanigans and a tombstone bit is set on the bucket pointer. the benefit here is that we are able to remove elements without forcing a memory allocation on the user. the interface of the insert_or_modify family of functions was changed to require a function that has both key and value parameters. imo there was never a solid reason not to do that, but this allows arbitrary data to be accessed from the old key before disposing of it. additionally, the Bucket/BucketArray classes were completely rewritten and moved into a module of their own. i am more satisfied with the amount of code duplication now, but i believe there is more work to be done to unify the implementations of get, insert, and remove. in the future, i hope to use this separate module to create a striped hash table similar to Java 7's ConcurrentHashMap. this should significantly increase write performance. note that this commit includes an internal remove_if interface, which is intended to address #7. * move map tests into crate::map::tests * add bucket key/value destructor tests ensure that destructors are called for keys and values in a timely manner * correct growth policy to grow by a factor of 2 previous behavior would result in growing by a factor of 4 (!) * Add remove_if family of functions (#11) * add remove_if family of functions `remove_if` and friends accept a condition function, which is `impl FnMut(&K, &V) -> bool`. If the condition returns true immediately before attempting to CAS the bucket pointer, the bucket is swapped. Otherwise, `None` is returned. * rewrite drivers to reduce number of function calls this way the backtraces will have one less function call listed * document remove_if functions * bump version to 0.3.0 A few breaking changes were made with the `modify` and `insert_or_modify` functions, so the next release requires a minor version bump (since we're in pre-1.0.0 territory)
- Loading branch information