Skip to content

Commit a6bba76

Browse files
committed
Make repository evmap-only
1 parent 849c661 commit a6bba76

30 files changed

+131
-1793
lines changed

Cargo.toml

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,36 @@
1-
[workspace]
2-
members = ["evmap", "left-right"]
1+
[package]
2+
name = "evmap"
3+
version = "11.0.0-alpha.6"
4+
authors = ["Jon Gjengset <[email protected]>"]
5+
edition = "2018"
6+
license = "MIT OR Apache-2.0"
7+
8+
description = "A lock-free, eventually consistent, concurrent multi-value map."
9+
repository = "https://github.com/jonhoo/rust-evmap.git"
10+
11+
keywords = ["map","multi-value","lock-free"]
12+
categories = ["concurrency", "data-structures"]
13+
14+
[badges]
15+
azure-devops = { project = "jonhoo/jonhoo", pipeline = "evmap", build = "8" }
16+
codecov = { repository = "jonhoo/rust-evmap", branch = "master", service = "github" }
17+
maintenance = { status = "passively-maintained" }
18+
19+
[features]
20+
default = []
21+
indexed = ["indexmap"]
22+
eviction = ["indexed", "rand"]
23+
amortize = ["indexmap-amortized", "hashbag/amortize"]
24+
25+
[dependencies]
26+
indexmap = { version = "1.6.1", optional = true }
27+
indexmap-amortized = { version = "1.6.1", optional = true }
28+
smallvec = "1.0.0"
29+
hashbag = "0.1.3"
30+
rand = { version = "0.7", default-features = false, features = ["alloc"], optional = true }
31+
left-right = { version = "0.11.0" }
32+
33+
[dev-dependencies]
34+
quickcheck = "0.9"
35+
quickcheck_macros = "0.9"
36+
rand = "0.7"

README.md

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,36 @@
1-
This crate holds the implementation of the `left-right` concurrency
2-
primitive, and its primary user `evmap`. See the documentation for each
3-
crate for details.
4-
5-
Left-right is a concurrency primitive for high concurrency reads over a
6-
single-writer data structure. The primitive keeps two copies of the
7-
backing data structure, one that is accessed by readers, and one that is
8-
access by the (single) writer. This enables all reads to proceed in
9-
parallel with minimal coordination, and shifts the coordination overhead
10-
to the writer. In the absence of writes, reads scale linearly with the
11-
number of cores.
12-
13-
[![Build Status](https://dev.azure.com/jonhoo/jonhoo/_apis/build/status/evmap?branchName=master)](https://dev.azure.com/jonhoo/jonhoo/_build/latest?definitionId=8&branchName=master)
14-
[![Codecov](https://codecov.io/github/jonhoo/rust-evmap/coverage.svg?branch=master)](https://codecov.io/gh/jonhoo/rust-evmap)
15-
16-
**left-right**
17-
18-
[![Crates.io](https://img.shields.io/crates/v/left-right.svg)](https://crates.io/crates/left-right)
19-
[![Documentation](https://docs.rs/left-right/badge.svg)](https://docs.rs/left-right/)
20-
21-
**evmap**
22-
231
[![Crates.io](https://img.shields.io/crates/v/evmap.svg)](https://crates.io/crates/evmap)
242
[![Documentation](https://docs.rs/evmap/badge.svg)](https://docs.rs/evmap/)
253

4+
A lock-free, eventually consistent, concurrent multi-value map.
5+
6+
This map implementation allows reads and writes to execute entirely in parallel, with no
7+
implicit synchronization overhead. Reads never take locks on their critical path, and neither
8+
do writes assuming there is a single writer (multi-writer is possible using a `Mutex`), which
9+
significantly improves performance under contention. It is backed by the
10+
concurrency primitive [`left-right`](https://crates.io/crates/left-right).
11+
12+
The trade-off exposed by this module is one of eventual consistency: writes are not visible to
13+
readers except following explicit synchronization. Specifically, readers only see the
14+
operations that preceeded the last call to `WriteHandle::flush` by a writer. This lets
15+
writers decide how stale they are willing to let reads get. They can refresh the map after
16+
every write to emulate a regular concurrent `HashMap`, or they can refresh only occasionally to
17+
reduce the synchronization overhead at the cost of stale reads.
18+
19+
For read-heavy workloads, the scheme used by this module is particularly useful. Writers can
20+
afford to refresh after every write, which provides up-to-date reads, and readers remain fast
21+
as they do not need to ever take locks.
22+
23+
The map is multi-value, meaning that every key maps to a *collection* of values. This
24+
introduces some memory cost by adding a layer of indirection through a `Vec` for each value,
25+
but enables more advanced use. This choice was made as it would not be possible to emulate such
26+
functionality on top of the semantics of this map (think about it -- what would the operational
27+
log contain?).
28+
29+
To facilitate more advanced use-cases, each of the two maps also carry some customizeable
30+
meta-information. The writers may update this at will, and when a refresh happens, the current
31+
meta will also be made visible to readers. This could be useful, for example, to indicate what
32+
time the refresh happened.
33+
2634
## Performance
2735

2836
**These benchmarks are outdated at this point, but communicate the right

azure-pipelines.yml

Lines changed: 65 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,68 @@
1-
stages:
2-
- stage: left_right
3-
jobs:
4-
- template: default.yml@templates
5-
parameters:
6-
minrust: 1.40.0
7-
dir: "left-right"
8-
- stage: evmap
9-
jobs:
10-
- template: default.yml@templates
11-
parameters:
12-
minrust: 1.48.0
13-
codecov_token: $(CODECOV_TOKEN_SECRET)
14-
dir: "evmap"
15-
- job: benchmark
16-
displayName: "Check that benchmark compiles"
17-
pool:
18-
vmImage: ubuntu-latest
19-
steps:
20-
- template: install-rust.yml@templates
21-
- script: cargo check
22-
displayName: cargo check benchmark/
23-
workingDirectory: "evmap/benchmark"
24-
- job: miri
25-
displayName: "Run miri on test suite"
26-
pool:
27-
vmImage: ubuntu-latest
28-
steps:
29-
- bash: |
30-
echo '##vso[task.setvariable variable=nightly]nightly-'$(curl -s https://rust-lang.github.io/rustup-components-history/x86_64-unknown-linux-gnu/miri)
31-
displayName: "Determine latest miri nightly"
32-
- template: install-rust.yml@templates
33-
parameters:
34-
rust: $(nightly)
35-
components:
36-
- miri
37-
- script: cargo miri setup
38-
displayName: cargo miri setup
39-
workingDirectory: "evmap"
40-
- script: cargo miri test
41-
displayName: cargo miri test
42-
workingDirectory: "evmap"
43-
env:
44-
QUICKCHECK_TESTS: 500
45-
- job: asan
46-
displayName: "Run address sanitizer on test suite"
47-
pool:
48-
vmImage: ubuntu-latest
49-
steps:
50-
- template: install-rust.yml@templates
51-
parameters:
52-
rust: nightly
53-
- bash: |
54-
sudo ln -s /usr/bin/llvm-symbolizer-6.0 /usr/bin/llvm-symbolizer
55-
displayName: Enable debug symbols
56-
# only --lib --tests b/c of https://github.com/rust-lang/rust/issues/53945
57-
- script: |
58-
env ASAN_OPTIONS="detect_odr_violation=0" RUSTFLAGS="-Z sanitizer=address" cargo test --lib --tests --target x86_64-unknown-linux-gnu
59-
displayName: cargo -Z sanitizer=address test
60-
workingDirectory: "evmap"
61-
- job: lsan
62-
displayName: "Run leak sanitizer on test suite"
63-
pool:
64-
vmImage: ubuntu-latest
65-
steps:
66-
- template: install-rust.yml@templates
67-
parameters:
68-
rust: nightly
69-
- bash: |
70-
sudo ln -s /usr/bin/llvm-symbolizer-6.0 /usr/bin/llvm-symbolizer
71-
sed -i '/\[features\]/i [profile.dev]' Cargo.toml
72-
sed -i '/profile.dev/a opt-level = 1' Cargo.toml
73-
cat Cargo.toml
74-
displayName: Enable debug symbols
75-
- script: |
76-
env RUSTFLAGS="-Z sanitizer=leak" cargo test --target x86_64-unknown-linux-gnu
77-
displayName: cargo -Z sanitizer=leak test
78-
workingDirectory: "evmap"
1+
jobs:
2+
- template: default.yml@templates
3+
parameters:
4+
minrust: 1.48.0
5+
codecov_token: $(CODECOV_TOKEN_SECRET)
6+
- job: benchmark
7+
displayName: "Check that benchmark compiles"
8+
pool:
9+
vmImage: ubuntu-latest
10+
steps:
11+
- template: install-rust.yml@templates
12+
- script: cargo check
13+
displayName: cargo check benchmark/
14+
workingDirectory: "benchmark"
15+
- job: miri
16+
displayName: "Run miri on test suite"
17+
pool:
18+
vmImage: ubuntu-latest
19+
steps:
20+
- bash: |
21+
echo '##vso[task.setvariable variable=nightly]nightly-'$(curl -s https://rust-lang.github.io/rustup-components-history/x86_64-unknown-linux-gnu/miri)
22+
displayName: "Determine latest miri nightly"
23+
- template: install-rust.yml@templates
24+
parameters:
25+
rust: $(nightly)
26+
components:
27+
- miri
28+
- script: cargo miri setup
29+
displayName: cargo miri setup
30+
- script: cargo miri test
31+
displayName: cargo miri test
32+
env:
33+
QUICKCHECK_TESTS: 500
34+
- job: asan
35+
displayName: "Run address sanitizer on test suite"
36+
pool:
37+
vmImage: ubuntu-latest
38+
steps:
39+
- template: install-rust.yml@templates
40+
parameters:
41+
rust: nightly
42+
- bash: |
43+
sudo ln -s /usr/bin/llvm-symbolizer-6.0 /usr/bin/llvm-symbolizer
44+
displayName: Enable debug symbols
45+
# only --lib --tests b/c of https://github.com/rust-lang/rust/issues/53945
46+
- script: |
47+
env ASAN_OPTIONS="detect_odr_violation=0" RUSTFLAGS="-Z sanitizer=address" cargo test --lib --tests --target x86_64-unknown-linux-gnu
48+
displayName: cargo -Z sanitizer=address test
49+
- job: lsan
50+
displayName: "Run leak sanitizer on test suite"
51+
pool:
52+
vmImage: ubuntu-latest
53+
steps:
54+
- template: install-rust.yml@templates
55+
parameters:
56+
rust: nightly
57+
- bash: |
58+
sudo ln -s /usr/bin/llvm-symbolizer-6.0 /usr/bin/llvm-symbolizer
59+
sed -i '/\[features\]/i [profile.dev]' Cargo.toml
60+
sed -i '/profile.dev/a opt-level = 1' Cargo.toml
61+
cat Cargo.toml
62+
displayName: Enable debug symbols
63+
- script: |
64+
env RUSTFLAGS="-Z sanitizer=leak" cargo test --target x86_64-unknown-linux-gnu
65+
displayName: cargo -Z sanitizer=leak test
7966
8067
resources:
8168
repositories:
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)