X-Git-Url: http://plrg.eecs.uci.edu/git/?p=junction.git;a=blobdiff_plain;f=README.md;h=7f8c103d9776a924d081c6eb571c9908853a0900;hp=1bf35aceebc94ba2b779e949fd071cf53ff22fdd;hb=HEAD;hpb=6ec01ea117c6657e77b5eb36a684b3d2f99bf322 diff --git a/README.md b/README.md index 1bf35ac..7f8c103 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ -Junction is a library of concurrent data structures in C++. It contains three hash map implementations: +Junction is a library of concurrent data structures in C++. It contains several hash map implementations: + junction::ConcurrentMap_Crude junction::ConcurrentMap_Linear - junction::ConcurrentMap_LeapFrog + junction::ConcurrentMap_Leapfrog junction::ConcurrentMap_Grampa [CMake](https://cmake.org/) and [Turf](https://github.com/preshing/turf) are required. See the blog post [New Concurrent Hash Maps for C++](http://preshing.com/20160201/new-concurrent-hash-maps-for-cpp/) for more information. @@ -80,7 +81,7 @@ This will create the following file structure: ## Configuration -When you first run CMake on Junction, Turf will detect the capabilities of your compiler and write the results to a file in the build tree named `include/turf_config.h`. Similarly, Junction will write `include/junction_config.h` to the build tree. You can modify the contents of those files by setting variables when CMake runs. This can be done by passing additional options to `cmake`, or by using an interactive GUI such as `cmake-gui` or `ccmake`. +When you first run CMake on Junction, Turf will detect the capabilities of your compiler and write the results to a file in the build tree named `turf/include/turf_config.h`. Similarly, Junction will write `include/junction_config.h` to the build tree. You can modify the contents of those files by setting variables when CMake runs. This can be done by passing additional options to `cmake`, or by using an interactive GUI such as `cmake-gui` or `ccmake`. For example, to configure Turf to use the C++11 standard library, you can set the `TURF_PREFER_CPP11` variable on the command line: @@ -96,6 +97,19 @@ Many header files in Turf, and some in Junction, are configurable using preproce The `JUNCTION_USERCONFIG` variable works in a similar way. As an example, take a look at the Python script `junction/samples/MapScalabilityTests/TestAllMaps.py`. This script invokes `cmake` several times, passing a different `junction_userconfig.h.in` file each time. That's how it builds the same test application using different map implementations. +## Rules and Behavior + +Currently, Junction maps only work with keys and values that are pointers or pointer-sized integers. The hash function must be invertible, so that every key has a unique hash. Out of all possible keys, a _null_ key must be reserved, and out of all possible values, _null_ and _redirect_ values must be reserved. The defaults are 0 and 1. You can override those defaults by passing custom `KeyTraits` and `ValueTraits` parameters to the template. + +Every thread that manipulates a Junction map must periodically call `junction::DefaultQSBR.update`, as mentioned [in the blog post](http://preshing.com/20160201/new-concurrent-hash-maps-for-cpp/). If not, the application will leak memory. + +Otherwise, a Junction map is a lot like a big array of `std::atomic<>` variables, where the key is an index into the array. More precisely: + +* All of a Junction map's member functions, together with its `Mutator` member functions, are atomic with respect to each other, so you can safely call them from any thread without mutual exclusion. +* If an `assign` [happens before](http://preshing.com/20130702/the-happens-before-relation/) a `get` with the same key, the `get` will return the value it inserted, except if another operation changes the value in between. Any [synchronizing operation](http://preshing.com/20130823/the-synchronizes-with-relation/) will establish this relationship. +* For Linear, Leapfrog and Grampa maps, `assign` is a [release](http://preshing.com/20120913/acquire-and-release-semantics/) operation and `get` is a [consume](http://preshing.com/20140709/the-purpose-of-memory_order_consume-in-cpp11/) operation, so you can safely pass non-atomic information between threads using a pointer. For Crude maps, all operations are relaxed. +* In the current version, you must not `assign` while concurrently using an `Iterator`. + ## Feedback If you have any feedback on improving these steps, feel free to [open an issue](https://github.com/preshing/junction/issues) on GitHub, or send a direct message using the [contact form](http://preshing.com/contact/) on my blog.