Skip to content

Commit 89184d4

Browse files
committed
Auto merge of #417 - zakarumych:master, r=Amanieu
Add support for allocator-api2 This change allows using hashbrown with other crates that support `allocator-api2`. It opens possibility for any allocator that supports `allocator-api2` to be used with `hashbrown`. `allocator-api2` mimics types and functions of unstable `allocator-api` feature but works on stable. `hashbrown` will be using `allocator-api2` only when `"nightly" feature is not enabled. Typical use-case for `allocator-api2` is to use it both with and without `"nightly" feature, however `hashbrown` is special-case since it is built as part of `std` and `allocator-api2` is not ready for this. If fitzgen/bumpalo#201 is accepted, explicit support for `bumpalo` would be obsolete. *caveat*: Either `"nightly"`, `"allocator-api2"` or both features should be enabled for `hashbrown` to compile.
2 parents f76a340 + 326e80d commit 89184d4

File tree

9 files changed

+71
-59
lines changed

9 files changed

+71
-59
lines changed

.github/workflows/rust.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ jobs:
5050
thumbv6m-none-eabi,
5151
x86_64-pc-windows-gnu,
5252
]
53-
channel: [1.61.0, nightly]
53+
channel: [1.63.0, nightly]
5454
include:
5555
- os: macos-latest
5656
target: x86_64-apple-darwin
@@ -60,13 +60,13 @@ jobs:
6060
channel: nightly
6161
- os: macos-latest
6262
target: x86_64-apple-darwin
63-
channel: 1.61.0
63+
channel: 1.63.0
6464
- os: windows-latest
6565
target: x86_64-pc-windows-msvc
66-
channel: 1.61.0
66+
channel: 1.63.0
6767
- os: ubuntu-latest
6868
target: x86_64-unknown-linux-gnu
69-
channel: 1.61.0
69+
channel: 1.63.0
7070
- os: ubuntu-latest
7171
target: x86_64-unknown-linux-gnu
7272
channel: beta

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
77

88
## [Unreleased]
99

10+
### Added
11+
12+
- Support for `allocator-api2` crate
13+
for interfacing with custom allocators on stable.
14+
15+
### Changed
16+
17+
- Bumped MSRV to 1.63.0.
18+
19+
### Removed
20+
21+
- Support for `bumpalo` as an allocator with custom wrapper.
22+
Use `allocator-api2` feature in `bumpalo` to use it as an allocator
23+
for `hashbrown` collections.
24+
1025
## [v0.13.2] - 2023-01-12
1126

1227
### Fixed

Cargo.toml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ keywords = ["hash", "no_std", "hashmap", "swisstable"]
1010
categories = ["data-structures", "no-std"]
1111
exclude = [".github", "/ci/*"]
1212
edition = "2021"
13-
rust-version = "1.61.0"
13+
rust-version = "1.63.0"
1414

1515
[dependencies]
1616
# For the default hasher
@@ -25,8 +25,8 @@ core = { version = "1.0.0", optional = true, package = "rustc-std-workspace-core
2525
compiler_builtins = { version = "0.1.2", optional = true }
2626
alloc = { version = "1.0.0", optional = true, package = "rustc-std-workspace-alloc" }
2727

28-
# Optional support for bumpalo
29-
bumpalo = { version = "3.5.0", optional = true }
28+
# Support for allocators that use allocator-api2
29+
allocator-api2 = { version = "0.2.9", optional = true, default-features = false, features = ["alloc"] }
3030

3131
[dev-dependencies]
3232
lazy_static = "1.4"
@@ -35,11 +35,13 @@ rayon = "1.0"
3535
fnv = "1.0.7"
3636
serde_test = "1.0"
3737
doc-comment = "0.3.1"
38+
bumpalo = "3.6.0"
3839

3940
[features]
40-
default = ["ahash", "inline-more"]
41+
default = ["ahash", "inline-more", "allocator-api2"]
42+
43+
nightly = ["allocator-api2?/nightly", "bumpalo/allocator_api"]
4144

42-
nightly = []
4345
rustc-internal-api = []
4446
rustc-dep-of-std = [
4547
"nightly",

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ hashbrown
44
[![Build Status](https://github.com/rust-lang/hashbrown/actions/workflows/rust.yml/badge.svg)](https://github.com/rust-lang/hashbrown/actions)
55
[![Crates.io](https://img.shields.io/crates/v/hashbrown.svg)](https://crates.io/crates/hashbrown)
66
[![Documentation](https://docs.rs/hashbrown/badge.svg)](https://docs.rs/hashbrown)
7-
[![Rust](https://img.shields.io/badge/rust-1.61.0%2B-blue.svg?maxAge=3600)](https://github.com/rust-lang/hashbrown)
7+
[![Rust](https://img.shields.io/badge/rust-1.63.0%2B-blue.svg?maxAge=3600)](https://github.com/rust-lang/hashbrown)
88

99
This crate is a Rust port of Google's high-performance [SwissTable] hash
1010
map, adapted to make it a drop-in replacement for Rust's standard `HashMap`
@@ -105,8 +105,8 @@ This crate has the following Cargo features:
105105
- `raw`: Enables access to the experimental and unsafe `RawTable` API.
106106
- `inline-more`: Adds inline hints to most functions, improving run-time performance at the cost
107107
of compilation time. (enabled by default)
108-
- `bumpalo`: Provides a `BumpWrapper` type which allows `bumpalo` to be used for memory allocation.
109108
- `ahash`: Compiles with ahash as default hasher. (enabled by default)
109+
- `allocator-api2`: Enables support for allocators that support `allocator-api2`. (enabled by default)
110110

111111
## License
112112

ci/run.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ if [ "${NO_STD}" = "1" ]; then
99
FEATURES="rustc-internal-api"
1010
OP="build"
1111
else
12-
FEATURES="rustc-internal-api,serde,rayon,raw,bumpalo"
12+
FEATURES="rustc-internal-api,serde,rayon,raw"
1313
OP="test"
1414
fi
1515
if [ "${CHANNEL}" = "nightly" ]; then

ci/tools.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ if retry rustup component add rustfmt ; then
3030
fi
3131

3232
if retry rustup component add clippy ; then
33-
cargo clippy --all --tests --features serde,rayon,bumpalo -- -D clippy::all
33+
cargo clippy --all --tests --features serde,rayon -- -D clippy::all
3434
cargo clippy --all --tests --features raw -- -D clippy::all
3535
fi
3636

src/lib.rs

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -164,21 +164,3 @@ pub enum TryReserveError {
164164
layout: alloc::alloc::Layout,
165165
},
166166
}
167-
168-
/// Wrapper around `Bump` which allows it to be used as an allocator for
169-
/// `HashMap`, `HashSet` and `RawTable`.
170-
///
171-
/// `Bump` can be used directly without this wrapper on nightly if you enable
172-
/// the `allocator-api` feature of the `bumpalo` crate.
173-
#[cfg(feature = "bumpalo")]
174-
#[derive(Clone, Copy, Debug)]
175-
pub struct BumpWrapper<'a>(pub &'a bumpalo::Bump);
176-
177-
#[cfg(feature = "bumpalo")]
178-
#[test]
179-
fn test_bumpalo() {
180-
use bumpalo::Bump;
181-
let bump = Bump::new();
182-
let mut map = HashMap::new_in(BumpWrapper(&bump));
183-
map.insert(0, 1);
184-
}

src/map.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -368,13 +368,13 @@ impl<K, V, A: Allocator + Clone> HashMap<K, V, DefaultHashBuilder, A> {
368368
/// # Examples
369369
///
370370
/// ```
371-
/// # #[cfg(feature = "bumpalo")]
371+
/// # #[cfg(feature = "nightly")]
372372
/// # fn test() {
373-
/// use hashbrown::{HashMap, BumpWrapper};
373+
/// use hashbrown::HashMap;
374374
/// use bumpalo::Bump;
375375
///
376376
/// let bump = Bump::new();
377-
/// let mut map = HashMap::new_in(BumpWrapper(&bump));
377+
/// let mut map = HashMap::new_in(&bump);
378378
///
379379
/// // The created HashMap holds none elements
380380
/// assert_eq!(map.len(), 0);
@@ -390,7 +390,7 @@ impl<K, V, A: Allocator + Clone> HashMap<K, V, DefaultHashBuilder, A> {
390390
/// assert!(map.capacity() > 1);
391391
/// # }
392392
/// # fn main() {
393-
/// # #[cfg(feature = "bumpalo")]
393+
/// # #[cfg(feature = "nightly")]
394394
/// # test()
395395
/// # }
396396
/// ```
@@ -419,13 +419,13 @@ impl<K, V, A: Allocator + Clone> HashMap<K, V, DefaultHashBuilder, A> {
419419
/// # Examples
420420
///
421421
/// ```
422-
/// # #[cfg(feature = "bumpalo")]
422+
/// # #[cfg(feature = "nightly")]
423423
/// # fn test() {
424-
/// use hashbrown::{HashMap, BumpWrapper};
424+
/// use hashbrown::HashMap;
425425
/// use bumpalo::Bump;
426426
///
427427
/// let bump = Bump::new();
428-
/// let mut map = HashMap::with_capacity_in(5, BumpWrapper(&bump));
428+
/// let mut map = HashMap::with_capacity_in(5, &bump);
429429
///
430430
/// // The created HashMap holds none elements
431431
/// assert_eq!(map.len(), 0);
@@ -446,7 +446,7 @@ impl<K, V, A: Allocator + Clone> HashMap<K, V, DefaultHashBuilder, A> {
446446
/// assert_eq!(map.capacity(), empty_map_capacity)
447447
/// # }
448448
/// # fn main() {
449-
/// # #[cfg(feature = "bumpalo")]
449+
/// # #[cfg(feature = "nightly")]
450450
/// # test()
451451
/// # }
452452
/// ```

src/raw/alloc.rs

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
pub(crate) use self::inner::{do_alloc, Allocator, Global};
22

3+
// Nightly-case.
4+
// Use unstable `allocator_api` feature.
5+
// This is compatible with `allocator-api2` which can be enabled or not.
6+
// This is used when building for `std`.
37
#[cfg(feature = "nightly")]
48
mod inner {
59
use crate::alloc::alloc::Layout;
@@ -13,22 +17,38 @@ mod inner {
1317
Err(_) => Err(()),
1418
}
1519
}
20+
}
1621

17-
#[cfg(feature = "bumpalo")]
18-
unsafe impl Allocator for crate::BumpWrapper<'_> {
19-
#[inline]
20-
fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, core::alloc::AllocError> {
21-
match self.0.try_alloc_layout(layout) {
22-
Ok(ptr) => Ok(NonNull::slice_from_raw_parts(ptr, layout.size())),
23-
Err(_) => Err(core::alloc::AllocError),
24-
}
22+
// Basic non-nightly case.
23+
// This uses `allocator-api2` enabled by default.
24+
// If any crate enables "nightly" in `allocator-api2`,
25+
// this will be equivalent to the nightly case,
26+
// since `allocator_api2::alloc::Allocator` would be re-export of
27+
// `core::alloc::Allocator`.
28+
#[cfg(all(not(feature = "nightly"), feature = "allocator-api2"))]
29+
mod inner {
30+
use crate::alloc::alloc::Layout;
31+
pub use allocator_api2::alloc::{Allocator, Global};
32+
use core::ptr::NonNull;
33+
34+
#[allow(clippy::map_err_ignore)]
35+
pub(crate) fn do_alloc<A: Allocator>(alloc: &A, layout: Layout) -> Result<NonNull<u8>, ()> {
36+
match alloc.allocate(layout) {
37+
Ok(ptr) => Ok(ptr.cast()),
38+
Err(_) => Err(()),
2539
}
26-
#[inline]
27-
unsafe fn deallocate(&self, _ptr: NonNull<u8>, _layout: Layout) {}
2840
}
2941
}
3042

31-
#[cfg(not(feature = "nightly"))]
43+
// No-defaults case.
44+
// When building with default-features turned off and
45+
// neither `nightly` nor `allocator-api2` is enabled,
46+
// this will be used.
47+
// Making it impossible to use any custom allocator with collections defined
48+
// in this crate.
49+
// Any crate in build-tree can enable `allocator-api2`,
50+
// or `nightly` without disturbing users that don't want to use it.
51+
#[cfg(not(any(feature = "nightly", feature = "allocator-api2")))]
3252
mod inner {
3353
use crate::alloc::alloc::{alloc, dealloc, Layout};
3454
use core::ptr::NonNull;
@@ -41,6 +61,7 @@ mod inner {
4161

4262
#[derive(Copy, Clone)]
4363
pub struct Global;
64+
4465
unsafe impl Allocator for Global {
4566
#[inline]
4667
fn allocate(&self, layout: Layout) -> Result<NonNull<u8>, ()> {
@@ -51,6 +72,7 @@ mod inner {
5172
dealloc(ptr.as_ptr(), layout);
5273
}
5374
}
75+
5476
impl Default for Global {
5577
#[inline]
5678
fn default() -> Self {
@@ -61,13 +83,4 @@ mod inner {
6183
pub(crate) fn do_alloc<A: Allocator>(alloc: &A, layout: Layout) -> Result<NonNull<u8>, ()> {
6284
alloc.allocate(layout)
6385
}
64-
65-
#[cfg(feature = "bumpalo")]
66-
unsafe impl Allocator for crate::BumpWrapper<'_> {
67-
#[allow(clippy::map_err_ignore)]
68-
fn allocate(&self, layout: Layout) -> Result<NonNull<u8>, ()> {
69-
self.0.try_alloc_layout(layout).map_err(|_| ())
70-
}
71-
unsafe fn deallocate(&self, _ptr: NonNull<u8>, _layout: Layout) {}
72-
}
7386
}

0 commit comments

Comments
 (0)