Skip to content

Commit 35e91e2

Browse files
committed
Change no_arc to arc, using Rc by default.
1 parent 6e3d933 commit 35e91e2

File tree

8 files changed

+102
-114
lines changed

8 files changed

+102
-114
lines changed

Diff for: CHANGELOG.md

+87-99
Original file line numberDiff line numberDiff line change
@@ -2,87 +2,80 @@
22

33
All notable changes to this project will be documented in this file.
44

5-
The format is based on [Keep a
6-
Changelog](http://keepachangelog.com/en/1.0.0/) and this project
7-
adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
5+
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
6+
and this project adheres to [Semantic
7+
Versioning](http://semver.org/spec/v2.0.0.html).
88

99
## [Unreleased]
1010
### Changed
1111

12-
This is a major release with many breaking changes, and is intended to
13-
stabilise the API more than to denote that the rewrite is now
14-
production ready. You should expect future releases with significant
15-
performance improvements as well as additional APIs, but there should
16-
be no further major release with breaking changes in the immediate
17-
future, barring very serious unforeseen issues.
12+
This is a major release with many breaking changes, and is intended to stabilise
13+
the API more than to denote that the rewrite is now production ready. You should
14+
expect future releases with significant performance improvements as well as
15+
additional APIs, but there should be no further major release with breaking
16+
changes in the immediate future, barring very serious unforeseen issues.
1817

19-
Specifically, you should expect imminent minor releases with
20-
performance improvements for `Vector` and `OrdMap`, for which I have a
21-
number of known optimisations that remain unimplemented.
18+
Specifically, you should expect imminent minor releases with performance
19+
improvements for `Vector` and `OrdMap`, for which I have a number of known
20+
optimisations that remain unimplemented.
2221

2322
#### No More `Arc`
2423

25-
All data structures have been reworked to take values of `A: Clone`
26-
instead of `Arc<A>`, meaning that there's less performance overhead
27-
(as well as mental overhead) when using values that clone cheaply. The
28-
performance gain when values are `A: Copy` is a factor of two or more.
29-
It's expected that users should wrap values in `Arc` themselves when
30-
using values which are expensive to clone.
24+
All data structures have been reworked to take values of `A: Clone` instead of
25+
`Arc<A>`, meaning that there's less performance overhead (as well as mental
26+
overhead) when using values that clone cheaply. The performance gain when values
27+
are `A: Copy` is a factor of two or more. It's expected that users should wrap
28+
values in `Arc` themselves when using values which are expensive to clone.
3129

32-
Data structures still use `Arc` internally to reference nodes, but
33-
values are stored directly in the nodes with no further indirection.
34-
This is also good for cache locality.
30+
Data structures still use reference counters internally to reference nodes, but
31+
values are stored directly in the nodes with no further indirection. This is
32+
also good for cache locality.
3533

36-
You can now also use the `no_arc` feature when compiling `im` to use
37-
`Rc` instead of `Arc` if you don't need the data structures to be
38-
`Send` or `Sync`, yielding another ~20% increase in performance.
34+
Data structures now use `Rc` instead of `Arc` by default to do reference
35+
counting. If you need a thread safe version that implements `Send` and `Sync`,
36+
you can enable the `arc` feature on the package to compile with `Arc` instead.
3937

4038
#### `std::collections` Compatible API
4139

42-
The API has been reworked to align more closely with
43-
`std::collections`, favouring mutable operations by default, so that
44-
operations that were previously suffixed with `_mut` are now the
45-
standard operations, and immutable operations which return a modified
46-
copy have been given different names altogether. In short, all your
47-
code using previous versions of this library will no longer work, and
48-
if it was relying heavily on immutable operations, it's recommended
49-
that you rewrite it to be mutable by preference, but you should
50-
generally be able to make it work again by using the new method names
51-
for the immutable operations.
40+
The API has been reworked to align more closely with `std::collections`,
41+
favouring mutable operations by default, so that operations that were previously
42+
suffixed with `_mut` are now the standard operations, and immutable operations
43+
which return a modified copy have been given different names altogether. In
44+
short, all your code using previous versions of this library will no longer
45+
work, and if it was relying heavily on immutable operations, it's recommended
46+
that you rewrite it to be mutable by preference, but you should generally be
47+
able to make it work again by using the new method names for the immutable
48+
operations.
5249

53-
Here is a list of the most notable changed method names for maps and
54-
sets:
50+
Here is a list of the most notable changed method names for maps and sets:
5551

5652
| Previous immutable | Current immutable | Previous mutable | Current mutable |
5753
| --- | --- | --- | --- |
5854
| `insert` | `update` | `insert_mut` | `insert` |
5955
| `remove` | `without` | `remove_mut` | `remove` |
6056
| `pop` | `extract` | `pop_mut` | `remove` |
6157

62-
You should expect to be able to rewrite code using
63-
`std::collections::HashMap` and `std::collections::BTreeMap` with
64-
minimal or no changes using `im::HashMap` and `im::OrdMap`
65-
respectively.
58+
You should expect to be able to rewrite code using `std::collections::HashMap`
59+
and `std::collections::BTreeMap` with minimal or no changes using `im::HashMap`
60+
and `im::OrdMap` respectively.
6661

6762
`Vector` has been completely rewritten and has an API that aligns closely with
68-
`std::collections::VecDeque`, with very few immutable equivalents.
69-
It's expected that you should use `Vector::clone()` to take a snapshot
70-
when you need it rather than cause an implicit clone for each
71-
operation. (It's still O(1) and practically instant.)
63+
`std::collections::VecDeque`, with very few immutable equivalents. It's expected
64+
that you should use `Vector::clone()` to take a snapshot when you need it rather
65+
than cause an implicit clone for each operation. (It's still O(1) and
66+
practically instant.)
7267

7368
#### RRB Vector
7469

7570
`Vector` is now implemented as an [RRB
76-
tree](https://infoscience.epfl.ch/record/213452/files/rrbvector.pdf)
77-
with [smart head/tail
78-
chunking](http://gallium.inria.fr/~rainey/chunked_seq.pdf), obsoleting
71+
tree](https://infoscience.epfl.ch/record/213452/files/rrbvector.pdf) with [smart
72+
head/tail chunking](http://gallium.inria.fr/~rainey/chunked_seq.pdf), obsoleting
7973
the previous [Hickey
8074
trie](https://hypirion.com/musings/understanding-persistent-vector-pt-1)
8175
implementation.
8276

83-
RRB trees have generally similar performance characteristics to the
84-
Hickey trie, with the added benefit of having O(log n) splitting and
85-
concatenation.
77+
RRB trees have generally similar performance characteristics to the Hickey trie,
78+
with the added benefit of having O(log n) splitting and concatenation.
8679

8780
| Operation | RRB tree | Hickey trie | Vec | VecDeque |
8881
| --- | --- | --- | --- | --- |
@@ -94,79 +87,74 @@ concatenation.
9487
| Split | O(log n) | O(log n) | O(n) | O(n) |
9588
| Join | O(log n) | O(n) | O(n) | O(n) |
9689

97-
(Please note that the timings above are for the `im` version of the
98-
Hickey trie, based on the
99-
[Immutable.js](https://facebook.github.io/immutable-js/)
100-
implementation, which performs better than the original Clojure
101-
version on splits and push/pop front, but worse on push/pop back).
102-
103-
The RRB tree is the most generally efficient list like data structure
104-
currently known, to my knowledge, but obviously it does not and cannot
105-
perform as well as a simple `Vec` on certain operations. It makes up
106-
for that by having no operations you need to worry about the
107-
performance complexity of: nothing you can do to an RRB tree is going
108-
to be more expensive than just iterating over it. For larger data
109-
sets, being able to concatenate (and, by extension, insert and remove
110-
at arbitrary locations) several orders of magnitude faster than `Vec`
90+
(Please note that the timings above are for the `im` version of the Hickey trie,
91+
based on the [Immutable.js](https://facebook.github.io/immutable-js/)
92+
implementation, which performs better than the original Clojure version on
93+
splits and push/pop front, but worse on push/pop back).
94+
95+
The RRB tree is the most generally efficient list like data structure currently
96+
known, to my knowledge, but obviously it does not and cannot perform as well as
97+
a simple `Vec` on certain operations. It makes up for that by having no
98+
operations you need to worry about the performance complexity of: nothing you
99+
can do to an RRB tree is going to be more expensive than just iterating over it.
100+
For larger data sets, being able to concatenate (and, by extension, insert and
101+
remove at arbitrary locations) several orders of magnitude faster than `Vec`
111102
could also be considered a selling point.
112103

113104
#### No More `CatList` And `ConsList`
114105

115-
`CatList` has been superseded by `Vector`, and `ConsList` was
116-
generally not very useful except in the more peculiar edge cases where
117-
memory consumption matters more than performance, and keeping it in
118-
line with current API changes wasn't practical.
106+
`CatList` has been superseded by `Vector`, and `ConsList` was generally not very
107+
useful except in the more peculiar edge cases where memory consumption matters
108+
more than performance, and keeping it in line with current API changes wasn't
109+
practical.
119110

120111
#### No More Funny Words
121112

122-
Though it breaks my heart, words like `cons`, `snoc`, `car`, `cdr` and
123-
`uncons` are no longer used in the `im` API, to facilitiate closer
124-
alignment with `std::collections`. Even the `head`/`tail` pair is
125-
gone, though `head` and `last` remain as aliases for `front` and
126-
`back`.
113+
Though it breaks my heart, words like `cons`, `snoc`, `car`, `cdr` and `uncons`
114+
are no longer used in the `im` API, to facilitiate closer alignment with
115+
`std::collections`. Even the `head`/`tail` pair is gone, though `head` and
116+
`last` remain as aliases for `front` and `back`.
127117

128118
## [10.2.0] - 2018-04-15
129119
### Added
130120

131-
* Map/set methods which accept references to keys will now also take
132-
any value that's borrowable to the key's type, ie. it will take a
133-
reference to a type `Borrowable` where the key implements
134-
`Borrow<Borrowable>`. This is particularly handy for types such as
135-
`String` because you can now pass `&str` to key lookups instead of
136-
`&String`. So, instead of the incredibly cumbersome
137-
`map.get(&"foo".to_string())` you can just do `map.get("foo")` when
138-
looking up a mapping for a string literal.
121+
* Map/set methods which accept references to keys will now also take any value
122+
that's borrowable to the key's type, ie. it will take a reference to a type
123+
`Borrowable` where the key implements `Borrow<Borrowable>`. This is
124+
particularly handy for types such as `String` because you can now pass `&str`
125+
to key lookups instead of `&String`. So, instead of the incredibly cumbersome
126+
`map.get(&"foo".to_string())` you can just do `map.get("foo")` when looking up
127+
a mapping for a string literal.
139128

140129
## [10.1.0] - 2018-04-12
141130
### Added
142131

143-
* `Vector`, `OrdMap` and `HashMap` now implement `Index` and
144-
`IndexMut`, allowing for syntax like `map[key] = value`.
132+
* `Vector`, `OrdMap` and `HashMap` now implement `Index` and `IndexMut`,
133+
allowing for syntax like `map[key] = value`.
145134
* Added `cons`, `snoc`, `uncons` and `unsnoc` aliases where they were missing.
146135
* Everything now implements `Sum` and `Extend` where possible.
147136

148137
### Changed
149138

150-
* Generalised `OrdMap`/`OrdSet`'s internal nodes so `OrdSet` now only
151-
needs to store pointers to its values, not pairs of pointers to
152-
value and `Unit`. This has caused `OrdMap/Set`'s type constraints to
153-
tighten somewhat - in particular, iteration over maps/sets whose
154-
keys don't implement `Ord` is no longer possible, but as you would
155-
only have been able to create empty instances of these, no sensible
156-
code should break because of this.
157-
* `HashMap`/`HashSet` now also cannot be iterated over unless they
158-
implement `Hash + Eq`, with the same note as above.
159-
* Constraints on single operations that take closures on `HashMap` and
160-
`OrdMap` have been relaxed from `Fn` to `FnOnce`. (Fixes #7.)
139+
* Generalised `OrdMap`/`OrdSet`'s internal nodes so `OrdSet` now only needs to
140+
store pointers to its values, not pairs of pointers to value and `Unit`. This
141+
has caused `OrdMap/Set`'s type constraints to tighten somewhat - in
142+
particular, iteration over maps/sets whose keys don't implement `Ord` is no
143+
longer possible, but as you would only have been able to create empty
144+
instances of these, no sensible code should break because of this.
145+
* `HashMap`/`HashSet` now also cannot be iterated over unless they implement
146+
`Hash + Eq`, with the same note as above.
147+
* Constraints on single operations that take closures on `HashMap` and `OrdMap`
148+
have been relaxed from `Fn` to `FnOnce`. (Fixes #7.)
161149

162150
### Fixed
163151

164-
* Hashes are now stored in `HashMap`s along with their associated
165-
values, removing the need to recompute the hash when a value is
166-
reordered inside the tree.
152+
* Hashes are now stored in `HashMap`s along with their associated values,
153+
removing the need to recompute the hash when a value is reordered inside the
154+
tree.
167155

168156
## [10.0.0] - 2018-03-25
169157
### Added
170158

171-
This is the first release to be considered reasonably stable. No
172-
changelog has been kept until now.
159+
This is the first release to be considered reasonably stable. No changelog has
160+
been kept until now.

Diff for: Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ travis-ci = { repository = "bodil/im-rs" }
1919
rustc_version = "0.2"
2020

2121
[features]
22-
no_arc = []
22+
arc = []
2323

2424
[dependencies]
2525
quickcheck = { version = "0.6", optional = true }

Diff for: src/hashmap.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1752,10 +1752,10 @@ where
17521752

17531753
// QuickCheck
17541754

1755-
#[cfg(all(not(feature = "no_arc"), any(test, feature = "quickcheck")))]
1755+
#[cfg(all(feature = "arc", any(test, feature = "quickcheck")))]
17561756
use quickcheck::{Arbitrary, Gen};
17571757

1758-
#[cfg(all(not(feature = "no_arc"), any(test, feature = "quickcheck")))]
1758+
#[cfg(all(feature = "arc", any(test, feature = "quickcheck")))]
17591759
impl<K: Hash + Eq + Arbitrary + Sync, V: Arbitrary + Sync> Arbitrary for HashMap<K, V> {
17601760
fn arbitrary<G: Gen>(g: &mut G) -> Self {
17611761
HashMap::from(Vec::<(K, V)>::arbitrary(g))

Diff for: src/hashset.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -854,10 +854,10 @@ where
854854

855855
// QuickCheck
856856

857-
#[cfg(all(not(feature = "no_arc"), any(test, feature = "quickcheck")))]
857+
#[cfg(all(feature = "arc", any(test, feature = "quickcheck")))]
858858
use quickcheck::{Arbitrary, Gen};
859859

860-
#[cfg(all(not(feature = "no_arc"), any(test, feature = "quickcheck")))]
860+
#[cfg(all(feature = "arc", any(test, feature = "quickcheck")))]
861861
impl<A: Hash + Eq + Arbitrary + Sync> Arbitrary for HashSet<A> {
862862
fn arbitrary<G: Gen>(g: &mut G) -> Self {
863863
HashSet::from_iter(Vec::<A>::arbitrary(g))

Diff for: src/ordmap.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1601,10 +1601,10 @@ impl<'a, K: Ord + Hash + Eq + Clone, V: Clone, S: BuildHasher> From<&'a HashMap<
16011601

16021602
// QuickCheck
16031603

1604-
#[cfg(all(not(feature = "no_arc"), any(test, feature = "quickcheck")))]
1604+
#[cfg(all(feature = "arc", any(test, feature = "quickcheck")))]
16051605
use quickcheck::{Arbitrary, Gen};
16061606

1607-
#[cfg(all(not(feature = "no_arc"), any(test, feature = "quickcheck")))]
1607+
#[cfg(all(feature = "arc", any(test, feature = "quickcheck")))]
16081608
impl<K: Ord + Clone + Arbitrary + Sync, V: Clone + Arbitrary + Sync> Arbitrary for OrdMap<K, V> {
16091609
fn arbitrary<G: Gen>(g: &mut G) -> Self {
16101610
OrdMap::from_iter(Vec::<(K, V)>::arbitrary(g))

Diff for: src/ordset.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -819,10 +819,10 @@ impl<'a, A: Hash + Eq + Ord + Clone, S: BuildHasher> From<&'a HashSet<A, S>> for
819819

820820
// QuickCheck
821821

822-
#[cfg(all(not(feature = "no_arc"), any(test, feature = "quickcheck")))]
822+
#[cfg(all(feature = "arc", any(test, feature = "quickcheck")))]
823823
use quickcheck::{Arbitrary, Gen};
824824

825-
#[cfg(all(not(feature = "no_arc"), any(test, feature = "quickcheck")))]
825+
#[cfg(all(feature = "arc", any(test, feature = "quickcheck")))]
826826
impl<A: Ord + Clone + Arbitrary + Sync> Arbitrary for OrdSet<A> {
827827
fn arbitrary<G: Gen>(g: &mut G) -> Self {
828828
OrdSet::from_iter(Vec::<A>::arbitrary(g))

Diff for: src/util.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ use std::ops::IndexMut;
88
use std::ptr;
99

1010
// The `Ref` type is an alias for either `Rc` or `Arc`, user's choice.
11-
#[cfg(not(feature = "no_arc"))]
11+
#[cfg(feature = "arc")]
1212
use std::sync::Arc;
13-
#[cfg(not(feature = "no_arc"))]
13+
#[cfg(feature = "arc")]
1414
pub type Ref<A> = Arc<A>;
15-
#[cfg(feature = "no_arc")]
15+
#[cfg(not(feature = "arc"))]
1616
use std::rc::Rc;
17-
#[cfg(feature = "no_arc")]
17+
#[cfg(not(feature = "arc"))]
1818
pub type Ref<A> = Rc<A>;
1919

2020
pub fn clone_ref<A>(r: Ref<A>) -> A

Diff for: src/vector.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1588,10 +1588,10 @@ impl<A: Clone> FusedIterator for ConsumingIter<A> {}
15881588

15891589
// QuickCheck
15901590

1591-
#[cfg(all(not(feature = "no_arc"), any(test, feature = "quickcheck")))]
1591+
#[cfg(all(feature = "arc", any(test, feature = "quickcheck")))]
15921592
use quickcheck::{Arbitrary, Gen};
15931593

1594-
#[cfg(all(not(feature = "no_arc"), any(test, feature = "quickcheck")))]
1594+
#[cfg(all(feature = "arc", any(test, feature = "quickcheck")))]
15951595
impl<A: Arbitrary + Sync + Clone> Arbitrary for Vector<A> {
15961596
fn arbitrary<G: Gen>(g: &mut G) -> Self {
15971597
Vector::from_iter(Vec::<A>::arbitrary(g))

0 commit comments

Comments
 (0)