Mention limitation on value types in the README
[junction.git] / README.md
index c60c8e363fa71d9c928596b25e725c5ec1178a0b..266abe0f58a71ab253094e0222ed38d45020fcf4 100644 (file)
--- 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.
@@ -58,15 +59,25 @@ Some developers will prefer approach #3, but I encourage you to try approach #1
 
 If your project is already based on CMake, clone the Junction and Turf source trees somewhere, then call `add_subdirectory` on Junction's root folder from your own CMake script. This will add both Junction and Turf targets to your build system.
 
-If you use Git, you can add the Junction and Turf repositories as submodules. Otherwise, you can just copy the Junction and Turf source trees to your repository.
-
-[FIXME: Create a repository with a sample project that demonstrates this.]
+For a simple example, see the [junction-sample](https://github.com/preshing/junction-sample) repository.
 
 ### Building the Libraries Separately
 
 Generate Junction's build system using the steps described in the *Getting Started* section, then use it to build the libraries you need. Add these to your own build system. Make sure to generate static libraries to avoid linking parts of the library that aren't needed.
 
-[FIXME: Use CMake's install feature to generate a clean output tree, so users don't have to fiddle with include and library paths too much.]
+If you build the `install` target provided by Junction's CMake script, the build system will output a clean folder containing only the headers and libs that you need. You can add this to your own project using a single include path. Choose the output directory by specifying the `CMAKE_INSTALL_PREFIX` variable to CMake. Additionally, you can specify `JUNCTION_WITH_SAMPLES=OFF` to avoid building the samples. For example:
+
+    $ cmake -DCMAKE_INSTALL_PREFIX=~/junction-install -DJUNCTION_WITH_SAMPLES=OFF ..
+    $ cmake --build . --target install --config RelWithDebInfo
+
+Notes:
+
+* Instead of running the second `cmake` command, which runs the build system, you could run your build system directly. For example, `make install` on Unix, or build the INSTALL project in Visual Studio.
+* If using makefiles, you'll probably want to pass the additional option `-DCMAKE_BUILD_TYPE=RelWithDebInfo` to the first `cmake` command.
+
+This will create the following file structure:
+
+![Install folder](/docs/install-folder.png)
 
 ## Configuration
 
@@ -86,6 +97,15 @@ 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. 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.