Blazing fast immutable collection datatypes for Rust.

Related tags

Data structures imbl
Overview

imbl

Blazing fast immutable collection datatypes for Rust.

This is a fork of the im crate, which appears to be unmaintained. (This fork is not currently any better, but hope springs eternal.)

Documentation

Licence

Copyright 2017 Bodil Stokke

This software is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

Code of Conduct

Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.

Comments
  • Panic when appending two vectors

    Panic when appending two vectors

    While fuzzing some of my own code, I ran across a bug in imbl::Vector: append somehow panics!

    This happens when appending together big imbl::Vector<u8>s:

    thread 'main' panicked at 'Chunk::pop_front: can't pop from empty chunk', /home/miyuruasuka/.cargo/registry/src/github.com-1ecc6299db9ec823/sized-chunks-0.6.5/src/sized_chunk/mod.rs:399:13
    stack backtrace:
       0: std::panicking::begin_panic
                 at /rustc/c8dfcfe046a7680554bf4eb612bad840e7631c4b/library/std/src/panicking.rs:541:12
       1: sized_chunks::sized_chunk::Chunk<A,N>::pop_front
                 at /home/miyuruasuka/.cargo/registry/src/github.com-1ecc6299db9ec823/sized-chunks-0.6.5/src/sized_chunk/mod.rs:399:13
       2: imbl::nodes::rrb::Size::pop
                 at /home/miyuruasuka/.cargo/registry/src/github.com-1ecc6299db9ec823/imbl-1.0.1/./src/nodes/rrb.rs:110:37
       3: imbl::nodes::rrb::Size::pop
                 at /home/miyuruasuka/.cargo/registry/src/github.com-1ecc6299db9ec823/imbl-1.0.1/./src/nodes/rrb.rs:126:9
       4: imbl::nodes::rrb::Node<A>::push_chunk
                 at /home/miyuruasuka/.cargo/registry/src/github.com-1ecc6299db9ec823/imbl-1.0.1/./src/nodes/rrb.rs:610:25
       5: imbl::nodes::rrb::Node<A>::push_chunk
                 at /home/miyuruasuka/.cargo/registry/src/github.com-1ecc6299db9ec823/imbl-1.0.1/./src/nodes/rrb.rs:646:23
       6: imbl::vector::RRB<A>::push_middle
                 at /home/miyuruasuka/.cargo/registry/src/github.com-1ecc6299db9ec823/imbl-1.0.1/./src/vector/mod.rs:1637:19
       7: imbl::vector::Vector<A>::append
                 at /home/miyuruasuka/.cargo/registry/src/github.com-1ecc6299db9ec823/imbl-1.0.1/./src/vector/mod.rs:1053:21
    

    Does this ring a bell? I will try to find a minimal reproducible case tomorrow --- unfortunately, the fuzzing input that led to this is long and complicated.

    opened by nullchinchilla 12
  • Wondering about aligning some naming choices more towards std

    Wondering about aligning some naming choices more towards std

    This is just something I was wondering about, having used im on a number of projects, Sometimes there is just minor differences of naming between im and the std::collections.

    for instance in im difference in HashSet, and OrdSet is an alias for symmetric_difference, while in std difference is equivalent to the im function relative_complement.

    I'm not sure how I would go about aligning more closely in this case, probably deprecate, difference, remove it. then after a period of time introduce a feature to enable a difference alias for relative complement.

    I figured it was at least worth considering, if only to gauge reaction, but definitely feel free to close if compat is considered more important.

    opened by ratmice 6
  • style: Added a new .rustfmt.toml file to the root, and ran 'cargo +nightly fmt --workspace'.

    style: Added a new .rustfmt.toml file to the root, and ran 'cargo +nightly fmt --workspace'.

    This is my own rust formatting style file, fixed to try to keep everything within 80 columns wide so that I can see multiple files side by side. At this point, all trailing whitespace has been removed, every file ends with a newline, and all tabs have been converted to spaces.

    opened by ckaran 5
  • Is Clone necessary for the Debug implementation of Vector?

    Is Clone necessary for the Debug implementation of Vector?

    Hello, I'm wondering if the trait bound A: Clone when implementing Debug for Vector<A> is necessary. https://github.com/jneem/imbl/blob/3fd258cee59499cac0243822903497c83fb00e6a/src/vector/mod.rs#L1784 Previously those bounds are removed for maps and sets (see https://github.com/bodil/im-rs/issues/81). Can the same thing be done to Vector?

    opened by wsx-ucb 5
  • consider deleting the #[deny(unsafe_code)] in lib.rs

    consider deleting the #[deny(unsafe_code)] in lib.rs

    As seen here, src/lib.rs currently contains the following line.

    #![deny(unsafe_code, nonstandard_style)]
    

    However, imbl (as a fork of im) makes frequent use of #[allow(unsafe_code)]. A quick rg -cF '#[allow(unsafe_code)]' reveals the following 24 instances of allowed unsafe code throughout the library.

    src/vector/focus.rs:7
    src/vector/mod.rs:8
    src/nodes/hamt.rs:5
    src/nodes/btree.rs:3
    src/util.rs:1
    

    I think it's a little misleading to have the deny(unsafe_code) when we just go ahead and allow(unsafe_code) wherever we need it. It also adds a small development burden to have to add allow(unsafe_code) if you want/need to use unsafe.

    opened by vlmutolo 4
  • Arc support broken

    Arc support broken

    Hey, thank you for forking and taking your time to merge the fixes!

    Judging the commit e84fe764003a924bd5c04d4dd2f1e0accc3c3654 I assume that you've decided to only keep the arc version of im and ditch im-rc.

    So I am surprised to see, that the following code

    use std::sync::Mutex;
    use std::thread;
    
    extern crate imbl;
    
    fn main() {
        let x : Mutex<imbl::Vector<u32>> = Mutex::new(imbl::Vector::new());
    
        thread::spawn(move || {
          let _ = x;
        });
    }
    

    Compiles fine with the commit right before removing the Rc implementation

    [dependencies]
    imbl = {git="https://github.com/jneem/imbl.git", rev="67ce8b5976941fbf2d1c96f5c68e868a497237d8"}
    

    But doesn't compile after removing the Rc implementation

    [dependencies]
    imbl = {git="https://github.com/jneem/imbl.git", rev="e84fe764003a924bd5c04d4dd2f1e0accc3c3654"}
    
    error[E0277]: `Rc<sized_chunks::sized_chunk::Chunk<usize>>` cannot be sent between threads safely
       --> src/main.rs:10:5
        |
    10  |     thread::spawn(move || {
        |     ^^^^^^^^^^^^^ `Rc<sized_chunks::sized_chunk::Chunk<usize>>` cannot be sent between threads safely
        |
        = help: within `Vector<u32>`, the trait `Send` is not implemented for `Rc<sized_chunks::sized_chunk::Chunk<usize>>`
    

    I am using rustc 1.54.0 (a178d0322 2021-07-26) on Ubuntu 21.4

    opened by Robert42 4
  • Go through the im-rs PRs

    Go through the im-rs PRs

    • [ ] 104 (improve vec iterator performance. Has some bugs, but probably worthwhile fixing it up)
    • [x] 150
    • [x] 154
    • [x] 155 (clone for by-ref iterators. Blocked on changes to sized-chunks)
    • [x] 158
    • [x] 160 (Make empty hashmaps not depend on random state. I think this is better fixed by making hashmaps non-Hash (and maybe also non-Ord, see #175)
    • [x] 161 (Adds a convenience method, seems worthwhile. Get it in after 1.0, because 1.0 shouldn't change API)
    • [x] 163 (Merge smaller maps into larger ones)
    • [x] 164
    • [x] 165
    • [x] 168 (Lifetime change; not sem-ver compatible, so after 1.0)
    • [x] 170
    • [x] 173
    • [x] 176
    • [x] 177
    • [x] 178
    • [x] 179
    • [x] 180
    • [x] 183
    • [x] 184
    • [x] 186
    • [x] 189
    • [x] 191
    • [x] 192
    • [x] 193
    opened by jneem 4
  • deprecate the `difference` function.

    deprecate the `difference` function.

    Here is a PR as promised in issue #56

    I'd still like to go through the docs, and see if anything else jumps out at me, and wait for feedback from others though.

    Edit: The only usages of it are in the doctests for the alias itself afaict.

    opened by ratmice 3
  • imbl::HashMap is not covariant over the Key type.

    imbl::HashMap is not covariant over the Key type.

    When using a type with a lifetime parameter as key for imbl::HashMap, read-only methods like get will not accept keys with shorter lifetimes. For example:

    use imbl::HashMap;
    use std::borrow::Cow;
    
    #[derive(Clone, Debug, Hash, PartialEq, Eq)]
    struct Key<'a> {
        key1: Cow<'a, str>,
        key2: Cow<'a, str>,
    }
    
    fn main() {
        let mut map: HashMap<Key<'static>, String> = HashMap::new();
        map.insert(
            Key {
                key1: Cow::Borrowed("some key 1"),
                key2: Cow::Borrowed("some key 2"),
            },
            String::from("some value"),
        );
    
        let key1 = String::from("some key 1");
        let key2 = String::from("some key 2");
    
        eprintln!(
            "{:?}",
            map.get(&Key {
                key1: Cow::Borrowed(&key1),
                key2: Cow::Borrowed(&key2)
            })
        );
    }
    

    When compiling this, the compiler complains that key1 and key2 do not live long enough; it requires that they are borrowed for 'static, even though it seems get should only need the key being available for the duration of the function call. I believe this is due to imbl::HashMap being invariant over its key parameter. The same example compiles and works as expected using std::collections::HashMap.

    Would it be possible to make imbl::HashMap covariant over the key type? Or is there a reason this is not possible?

    opened by maartendeprez 3
  • Update arbitrary requirement from 0.4 to 1.0

    Update arbitrary requirement from 0.4 to 1.0

    Updates the requirements on arbitrary to permit the latest version.

    Changelog

    Sourced from arbitrary's changelog.

    1.0.1

    Released 2021-05-20.

    Added

    • Arbitrary impls for NonZeroX types #79
    • Arbitrary impls for all arrays using const generics #55
    • Arbitrary impls for Ipv4Addr and Ipv6Addr #84

    Fixed

    • Use fewer bytes for Unstructured::int_in_range() #80
    • Use correct range for char generation #83

    1.0.0

    Released 2020-02-24.

    See 1.0.0-rc1 and 1.0.0-rc2 for changes since 0.4.7, which was the last main line release.


    1.0.0-rc2

    Released 2021-02-09.

    Added

    • The Arbitrary trait is now implemented for &[u8]. #67

    Changed

    • Rename Unstructured#get_bytes to Unstructured#bytes. #70
    • Passing an empty slice of choices to Unstructured#choose returns an error. Previously it would panic. 71

    1.0.0-rc1

    Released 2020-11-25.

    Added

    • The Arbitrary trait is now implemented for &str. #63

    Changed

    ... (truncated)

    Commits

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 3
  • OrdSet cannot contain different objects which have equal ordering

    OrdSet cannot contain different objects which have equal ordering

    #[derive(Debug, Clone, Hash, PartialEq, Eq)]
    pub struct Node {
        pub ord: u32,
        pub id: u32,
    }
    
    impl PartialOrd for Node {
        fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
            Some(self.cmp(other))
        }
    }
    
    impl Ord for Node {
        fn cmp(&self, other: &Self) -> std::cmp::Ordering {
            self.ord.cmp(&other.ord)
        }
    }
    
    fn main() {
        use imbl::ordset::OrdSet;
        let mut s = OrdSet::<Node>::new();
        s.insert(Node { ord: 2, id: 1 });
        s.insert(Node { ord: 2, id: 2 });
        println!("{:?}", s.len()); // 1
    }
    
    

    The output is 1.

    opened by ImJeremyHe 2
  • Feed bug fixes to upstream

    Feed bug fixes to upstream

    It looks like im is starting to get some maintenance again, so might be useful to feed the bug fixes you've made (to Vector IIRC?) back upstream. And more broadly seeing if you can collaborate.

    opened by itamarst 1
  • `pool` feature doesn't exist but is required for pool functionality

    `pool` feature doesn't exist but is required for pool functionality

    A bunch of things critical for pooling to actually be used are gated under the pool feature (ex. HashMap::with_pool(), but the pool feature doesn't exist

    opened by Kixiron 1
  • Fix vector merge algorithm to prevent the tree depth from growing

    Fix vector merge algorithm to prevent the tree depth from growing

    Prompted by #33, I dug into Vector some more this weekend and I'm not super encouraged by what I found. I made some tweaks to support smaller branching factors (because when the branching factor is large then it's really hard to hit corner cases with proptesting and fuzzing), and I immediately ran into some failed tests. In particular, test_inserts caused a panic, and when debugging the panic I found that it was producing very large skinny trees. Now some issues may have been caused by my amateurish attempts to support smaller branching factors, but the skinny tree thing seems to be an issue in unmodified im also: if I modify test_inserts to make larger vectors, I see that vectors of length 40000ish already have tree height 7. But with a branching factor of 64, height 3 should already get us to 200k!

    Part of my difficulty is that I don't really understand the RRB merge algorithm. The description in the original paper is not really complete, in my opinion, and neither is the one in L'orange's Masters thesis. It appears I'm not the first person with this complaint, see this, and also this and this for more background. @nomad010 you said you had an independent re-implementation of the RRB algorithm -- do you have any thoughts on this?

    opened by jneem 15
  • Audit/document/remove unsafe code

    Audit/document/remove unsafe code

    We have unsafe code in a few places, and the invariants that need to be upheld are not always well-documented.

    • [x] in Vector::swap we use unsafe because rust doesn't know that pointers to different indices are non-overlapping. I think this is fine, although it could be removed at the cost of a clone() and an extra swap.
    • [ ] in the hash table, there is unsafe code in insert, because we need to move out of something before we're ready to move a new value in. This could be removed at the cost of an additional "uninitialized" enum variant in Entry. I'm not sure what the cost of that is.
    • [ ] there's some unsafe code related to the "pool" feature. This code is currently disabled in imbl (it's only relevant when using Rc instead of Arc, and we don't have that yet). This part is therefore a lower priority.
    • [ ] there is a bunch of unsafe code dealing with Focus and FocusMut. This will take some time to figure out. There's some subtlety in FocusMut::split_at and FocusMut::unmut.
    opened by jneem 10
Releases(v1.0.0)
Owner
null
Ternary search tree collection in rust

tst Ternary search tree collection in rust with similar API to std::collections as it possible. Ternary search tree is a type of trie (sometimes calle

Alexey Pervushin 20 Dec 7, 2022
Collection of Data Structures in Rust

cds - Collection of Data Structures !!! UNDER CONSTRUCTION !!! The version v0.0.1 is a crates.io placeholder. License Licensed under either of Apache

Rafael Buchbinder 2 May 23, 2022
K-dimensional tree in Rust for fast geospatial indexing and lookup

kdtree K-dimensional tree in Rust for fast geospatial indexing and nearest neighbors lookup Crate Documentation Usage Benchmark License Usage Add kdtr

Rui Hu 152 Jan 2, 2023
Fast, efficient, and robust memory reclamation for concurrent data structures

Seize Fast, efficient, and robust memory reclamation for concurrent data structures. Introduction Concurrent data structures are faced with the proble

Ibraheem Ahmed 240 Dec 23, 2022
Rust-algorithm-club - Learn algorithms and data structures with Rust

Rust Algorithm Club ?? ?? This repo is under construction. Most materials are written in Chinese. Check it out here if you are able to read Chinese. W

Weihang Lo 360 Dec 28, 2022
Array helpers for Rust's Vector and String types

array_tool Array helpers for Rust. Some of the most common methods you would use on Arrays made available on Vectors. Polymorphic implementations for

Daniel P. Clark 69 Dec 9, 2022
Generic array types in Rust

generic-array This crate implements generic array types for Rust. Requires minumum Rust version of 1.36.0, or 1.41.0 for From<[T; N]> implementations

Bartłomiej Kamiński 325 Dec 25, 2022
A priority queue for Rust with efficient change function.

PriorityQueue This crate implements a Priority Queue with a function to change the priority of an object. Priority and items are stored in an IndexMap

null 139 Dec 30, 2022
Roaring bitmap implementation for Rust

RoaringBitmap This is not yet production ready. The API should be mostly complete now. This is a Rust port of the Roaring bitmap data structure, initi

Roaring bitmaps: A better compressed bitset 552 Jan 1, 2023
Rust Persistent Data Structures

Rust Persistent Data Structures Rust Persistent Data Structures provides fully persistent data structures with structural sharing. Setup To use rpds a

Diogo Sousa 883 Dec 31, 2022
Rust crate to extend io::Read & io::Write types with progress callbacks

progress-streams Rust crate to provide progress callbacks for types which implement io::Read or io::Write. Examples Reader extern crate progress_strea

Pop!_OS 19 Dec 3, 2022
Parameterized routing for generic resources in Rust

Usher Usher provides an easy way to construct parameterized routing trees in Rust. The nodes of these trees is naturally generic, allowing Usher to le

Isaac Whitfield 34 Oct 22, 2022
RiteLinked - LinkedHashMap & LinkedHashSet in Rust

RiteLinked -- HashMap-like containers that hold their key-value pairs in a user controllable order RiteLinked provides more up to date versions of Lin

Rite Database 52 Aug 19, 2022
A proof of concept implementation of cyclic data structures in stable, safe, Rust.

A proof of concept implementation of cyclic data structures in stable, safe, Rust. This demonstrates the combined power of the static-rc crate and the

null 157 Dec 28, 2022
Doubly-Linked List Implementation in Rust

Doubly-Linked List Implementation in Rust Purely for educational and recreational purposes. For real world production please use std::collections::Lin

Tsoding 9 Jul 28, 2022
Rust library for string parsing of basic data structures.

afmt Simple rust library for parsing basic data structures from strings. Usage You can specify string formats to any strucute, via the use of the fmt

Eduard 4 May 8, 2021
Hash Table Implementation in Rust

Hash Table Implementation in Rust Purely for educational and recreational purposes. For real world production please use std::collections::HashMap. Fo

Tsoding 11 Sep 6, 2022
SegVec data structure for rust. Similar to Vec, but allocates memory in chunks of increasing size.

segvec This crate provides the SegVec data structure. It is similar to Vec, but allocates memory in chunks of increasing size, referred to as "segment

Jacob Ryan McCollum 30 Dec 16, 2022
Serde is a framework for serializing and deserializing Rust data structures efficiently and generically.

Serde is a framework for serializing and deserializing Rust data structures efficiently and generically.

null 6.5k Dec 31, 2022