Auto merge of #30426 - gereeter:btree-rewrite, r=Gankro
Despite being over 700 lines shorter, this implementation should use less memory than the previous one and is faster on at least insertions and iteration, the latter improving approximately 5x. Technically a [breaking-change] due to removal of deprecated functions. cc @apasel422 @Gankro @goyox86 Fixes #27865. <!-- Reviewable:start --> [<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/rust-lang/rust/30426) <!-- Reviewable:end -->
This commit is contained in:
commit
88463364bf
File diff suppressed because it is too large
Load Diff
@ -9,6 +9,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
mod node;
|
||||
mod search;
|
||||
pub mod map;
|
||||
pub mod set;
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
76
src/libcollections/btree/search.rs
Normal file
76
src/libcollections/btree/search.rs
Normal file
@ -0,0 +1,76 @@
|
||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use core::cmp::Ordering;
|
||||
|
||||
use borrow::Borrow;
|
||||
|
||||
use super::node::{Handle, NodeRef, marker};
|
||||
|
||||
use super::node::ForceResult::*;
|
||||
use self::SearchResult::*;
|
||||
|
||||
pub enum SearchResult<BorrowType, K, V, FoundType, GoDownType> {
|
||||
Found(Handle<NodeRef<BorrowType, K, V, FoundType>, marker::KV>),
|
||||
GoDown(Handle<NodeRef<BorrowType, K, V, GoDownType>, marker::Edge>)
|
||||
}
|
||||
|
||||
pub fn search_tree<BorrowType, K, V, Q: ?Sized>(
|
||||
mut node: NodeRef<BorrowType, K, V, marker::LeafOrInternal>,
|
||||
key: &Q
|
||||
) -> SearchResult<BorrowType, K, V, marker::LeafOrInternal, marker::Leaf>
|
||||
where Q: Ord, K: Borrow<Q> {
|
||||
|
||||
loop {
|
||||
match search_node(node, key) {
|
||||
Found(handle) => return Found(handle),
|
||||
GoDown(handle) => match handle.force() {
|
||||
Leaf(leaf) => return GoDown(leaf),
|
||||
Internal(internal) => {
|
||||
node = internal.descend();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn search_node<BorrowType, K, V, Type, Q: ?Sized>(
|
||||
node: NodeRef<BorrowType, K, V, Type>,
|
||||
key: &Q
|
||||
) -> SearchResult<BorrowType, K, V, Type, Type>
|
||||
where Q: Ord, K: Borrow<Q> {
|
||||
|
||||
match search_linear(&node, key) {
|
||||
(idx, true) => Found(
|
||||
Handle::new_kv(node, idx)
|
||||
),
|
||||
(idx, false) => SearchResult::GoDown(
|
||||
Handle::new_edge(node, idx)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn search_linear<BorrowType, K, V, Type, Q: ?Sized>(
|
||||
node: &NodeRef<BorrowType, K, V, Type>,
|
||||
key: &Q
|
||||
) -> (usize, bool)
|
||||
where Q: Ord, K: Borrow<Q> {
|
||||
|
||||
for (i, k) in node.keys().iter().enumerate() {
|
||||
match key.cmp(k.borrow()) {
|
||||
Ordering::Greater => {},
|
||||
Ordering::Equal => return (i, true),
|
||||
Ordering::Less => return (i, false)
|
||||
}
|
||||
}
|
||||
(node.keys().len(), false)
|
||||
}
|
||||
|
@ -43,8 +43,8 @@
|
||||
#![feature(iter_arith)]
|
||||
#![feature(iter_arith)]
|
||||
#![feature(lang_items)]
|
||||
#![feature(nonzero)]
|
||||
#![feature(num_bits_bytes)]
|
||||
#![feature(oom)]
|
||||
#![feature(pattern)]
|
||||
#![feature(shared)]
|
||||
#![feature(slice_bytes)]
|
||||
@ -55,7 +55,7 @@
|
||||
#![feature(unboxed_closures)]
|
||||
#![feature(unicode)]
|
||||
#![feature(unique)]
|
||||
#![feature(unsafe_no_drop_flag, filling_drop)]
|
||||
#![feature(unsafe_no_drop_flag)]
|
||||
#![cfg_attr(test, feature(clone_from_slice, rand, test))]
|
||||
|
||||
#![no_std]
|
||||
|
@ -346,6 +346,38 @@ fn test_bad_zst() {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_clone() {
|
||||
let mut map = BTreeMap::new();
|
||||
let size = 100;
|
||||
assert_eq!(map.len(), 0);
|
||||
|
||||
for i in 0..size {
|
||||
assert_eq!(map.insert(i, 10*i), None);
|
||||
assert_eq!(map.len(), i + 1);
|
||||
assert_eq!(map, map.clone());
|
||||
}
|
||||
|
||||
for i in 0..size {
|
||||
assert_eq!(map.insert(i, 100*i), Some(10*i));
|
||||
assert_eq!(map.len(), size);
|
||||
assert_eq!(map, map.clone());
|
||||
}
|
||||
|
||||
for i in 0..size/2 {
|
||||
assert_eq!(map.remove(&(i*2)), Some(i*200));
|
||||
assert_eq!(map.len(), size - i - 1);
|
||||
assert_eq!(map, map.clone());
|
||||
}
|
||||
|
||||
for i in 0..size/2 {
|
||||
assert_eq!(map.remove(&(2*i)), None);
|
||||
assert_eq!(map.remove(&(2*i+1)), Some(i*200 + 100));
|
||||
assert_eq!(map.len(), size/2 - i - 1);
|
||||
assert_eq!(map, map.clone());
|
||||
}
|
||||
}
|
||||
|
||||
mod bench {
|
||||
use std::collections::BTreeMap;
|
||||
use std::__rand::{Rng, thread_rng};
|
||||
|
Loading…
x
Reference in New Issue
Block a user