preshing/junction: Concurrent C++ Maps for Pointer Keys
Concurrent data structures in C++
At a glance
- What is it?
- Junction is a C++ library offering several concurrent hash map implementations, including ConcurrentMap_Crude, ConcurrentMap_Linear, ConcurrentMap_Leapfrog, and ConcurrentMap_Grampa. It targets applications that need concurrent pointer-keyed maps and can configure the library through CMake.
- Who is it for?
- Junction fits engineers who need concurrent pointer-keyed maps and are prepared to integrate its QSB lifecycle and custom license obligations. It is a poor fit for general-purpose key-value storage, non-invertible hash functions, or applications that cannot reserve null and redirect values.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 160 days ago.
- What is it written in?
- Mainly C++, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 21, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Junction's Four Concurrent Map Choices
Junction addresses a specific C++ problem: sharing hash maps across threads while storing values that are pointers or pointer-sized integers. The repository exposes four map types: `junction::ConcurrentMap_Crude`, `junction::ConcurrentMap_Linear`, `junction::ConcurrentMap_Leapfrog`, and `junction::ConcurrentMap_Grampa`. The README does not document a single preferred implementation or provide comparative performance results, so the names alone do not establish which one is best for a particular workload.
The library is aimed at developers who already understand low-level C++ concurrency and are willing to manage thread lifecycle details. That audience is narrower than users of `std::unordered_map`. Junction does not present itself as a general serialization library, database, or object container. Its map interface is constrained by the need to represent keys and values as machine-sized values and by reserved values used internally by the concurrent data structure.
The project also requires Turf, a separate C++ repository, and uses CMake to generate the build system. The generated system includes separate targets for Junction, Turf, and sample applications. This makes the library suitable for projects that already use CMake or that are willing to introduce it. The repository includes samples for correctness, linearizability, memory behavior, performance, and scalability, which gives adopters concrete entry points for examining each implementation.
Pointer Keys, Reserved Values, and the Map Mechanism
Junction maps accept keys and values that are pointers or pointer-sized integers. The hash function must be invertible, meaning each key must have a unique hash. This is stricter than the usual requirement for a hash map, where collisions can be resolved through buckets or comparison logic.
Junction reserves specific values. A null key must remain unavailable from the set of usable keys. Null and redirect values must also be reserved from the value space. The defaults are `0` for the null key and `0` and `1` for null and redirect values. Developers can replace these defaults by supplying custom `KeyTraits` and `ValueTraits` template parameters. That customization is part of the library's contract, not merely an optional convenience.
The README describes the internal model as a large array of `std::atomic<>` variables, with the key acting as an index into that array. It also lists multiple map implementations and links to a separate blog post for more information. The supplied documentation excerpt does not explain the complete synchronization algorithm, memory reclamation details, resize behavior, iterator guarantees, or ordering semantics for each implementation. Those points must be checked in the source code and sample programs before selecting a map for production use.
A further operational requirement is mandatory. Every thread that manipulates a Junction map must periodically call `junction::DefaultQSBR.update`. The README states that failing to do so causes the application to leak memory. This is a significant difference from a conventional map whose lifetime is managed entirely by its owning thread or shared owner.
Building Junction and Turf from Source
The documented setup starts by cloning Junction and Turf into adjacent folders. This is useful when the goal is to inspect the source or work with the full CMake build. On Unix-like systems, CMake generates a Makefile by default. On Windows, it creates a Visual Studio solution. The commands below follow the README's initial source checkout and build-directory sequence.
$ git clone https://github.com/preshing/junction.git
$ git clone https://github.com/preshing/turf.git
$ cd junction
$ mkdir build
$ cd build
$ cmake <additional options> ..After configuration, the build system should contain targets for Junction, Turf, and sample applications. The repository does not document one universal build command for every generator. On Windows, a specific Visual Studio generator can be selected:
$ cmake -G "Visual Studio 14 2015" ..The README also documents Xcode generation for OS X and an iOS toolchain configuration:
$ cmake -G "Xcode" ..$ cmake -G "Xcode" -DCMAKE_TOOLCHAIN_FILE=../../turf/cmake/toolchains/iOS.cmake ..For a narrower first build, the README points to `samples/MapCorrectnessTests`, which can be configured in its own build directory using the same CMake process. The repository includes several other samples, but the excerpt does not provide their command-line instructions or expected output.
Installing Junction Through CMake
Junction can be integrated into an existing CMake project with `add_subdirectory`, linked after building the libraries, or copied as selected source files. The README favors the first two approaches because they make later updates easier to incorporate. It specifically warns that copying individual files can leave a project without a clean path for receiving upstream changes.
For separate installation, CMake can produce a folder containing the headers and libraries required by a consumer. The documented configuration disables sample targets with `JUNCTION_WITH_SAMPLES=OFF` and selects an installation directory with `CMAKE_INSTALL_PREFIX`:
$ cmake -DCMAKE_INSTALL_PREFIX=~/junction-install -DJUNCTION_WITH_SAMPLES=OFF ..
$ cmake --build . --target install --config RelWithDebInfoThe README says to prefer static libraries so that unused parts are excluded by the linker. On Makefile-based systems, it also suggests configuring with `-DCMAKE_BUILD_TYPE=RelWithDebInfo` before the build.
CMake performs configuration checks for both Turf and Junction. It writes `turf/include/turf_config.h` and `include/junction_config.h` in the build tree. Configuration can be changed through CMake options or a GUI such as `cmake-gui` or `ccmake`. For example, Turf can be configured to use the C++11 standard library:
$ cmake -DTURF_PREFER_CPP11=1 ..Junction and Turf also support user configuration headers through `JUNCTION_USERCONFIG` and `TURF_USERCONFIG`. These variables are useful for selecting implementation-specific settings, but the README does not enumerate every supported macro or configuration combination.
License, Maintenance, and Adoption Boundaries
Junction uses the Simplified BSD License. The README states that the source may be used in any project, including commercial applications, provided that credit is given by publishing the contents of the `LICENSE` file in project documentation. That is a licensing condition to include in an adoption review, not a guarantee that a particular integration is suitable for every codebase.
The repository is not archived, and its last push was on 2026-05-16. The repository has no GitHub releases, so there is no release history or tagged upgrade path documented by the supplied information. Recent source activity does not remove the need to inspect compiler compatibility, unresolved API questions, and the consequences of changing map implementations. The absence of releases also makes it especially important to retain the exact revision used by an application.
The clearest boundary is workload and interface suitability. Junction is not suitable when keys or values are strings, structs, or arbitrary objects unless they are represented through the supported pointer-sized types. It is also unsuitable when the hash function cannot be invertible. Applications that cannot guarantee periodic `DefaultQSBR.update` calls should not use it without first designing a lifecycle and reclamation strategy. A conventional `std::unordered_map`, protected by application-level synchronization, takes a different approach: it avoids these map-specific reserved values and QSB requirements but does not provide the concurrent behavior that Junction targets. The choice therefore depends on whether concurrent access and the documented map constraints matter more than general key and value support.
Editorial conclusion
Junction fits engineers who need concurrent pointer-keyed maps and are prepared to integrate its QSB lifecycle and custom license obligations. It is a poor fit for general-purpose key-value storage, non-invertible hash functions, or applications that cannot reserve null and redirect values. Verify compiler configuration, the selected map implementation, `DefaultQSBR.update` calls, and the required `LICENSE` attribution before adoption.
Frequently asked questions
What concurrent data structures does preshing/junction provide?
Junction provides four concurrent hash map implementations: `ConcurrentMap_Crude`, `ConcurrentMap_Linear`, `ConcurrentMap_Leapfrog`, and `ConcurrentMap_Grampa`. The README lists the types but does not provide comparative benchmark results.
How do I install preshing/junction with CMake?
Clone Junction and Turf, run CMake from a build directory, and optionally set `CMAKE_INSTALL_PREFIX` and `JUNCTION_WITH_SAMPLES=OFF`. The documented install target is invoked with `cmake --build . --target install --config RelWithDebInfo`.
What must I do before using a preshing/junction map in a multithreaded program?
Every thread that manipulates a Junction map must periodically call `junction::DefaultQSBR.update`. The README states that omitting these calls causes the application to leak memory. Keys and values must also be pointers or pointer-sized integers, and the hash function must be invertible.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/preshing-junction)Was this useful?