Skip to content

Commit 40bd9b8

Browse files
authored
Merge pull request #32 from orxfun/major-revision-v3
major-revision-v3
2 parents 9fafd7b + 4e1dc60 commit 40bd9b8

File tree

125 files changed

+12072
-4875
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

125 files changed

+12072
-4875
lines changed

Cargo.toml

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,31 @@
11
[package]
22
name = "orx-linked-list"
3-
version = "2.7.0"
3+
version = "3.0.0"
44
edition = "2021"
55
authors = ["orxfun <orx.ugur.arikan@gmail.com>"]
6-
description = "An efficient and recursive singly and doubly linked list implementation."
6+
description = "A linked list implementation with unique features and an extended list of constant time methods providing high performance traversals and mutations."
77
license = "MIT"
88
repository = "https://github.com/orxfun/orx-linked-list/"
9-
keywords = ["linked", "list", "vec", "array", "pinned"]
10-
categories = ["data-structures", "rust-patterns"]
9+
keywords = ["linked", "list", "doubly", "singly", "pinned"]
10+
categories = ["data-structures", "rust-patterns", "no-std"]
1111

1212
[dependencies]
13-
orx-pseudo-default = "1.2"
14-
orx-pinned-vec = "3.3"
15-
orx-split-vec = "3.3"
16-
orx-selfref-col = "1.8"
17-
13+
orx-pseudo-default = { version = "1.4", default-features = false }
14+
orx-pinned-vec = "3.9"
15+
orx-split-vec = "3.9"
16+
orx-selfref-col = "2.0"
1817

1918
[dev-dependencies]
20-
rand = "0.8"
21-
rand_chacha = "0.3"
22-
criterion = { version = "0.5", features = ["html_reports"] }
23-
test-case = "3.3"
19+
clap = { version = "4.5.17", features = ["derive"] }
20+
criterion = "0.5"
21+
rand = "0.8.5"
22+
rand_chacha = "0.3.1"
23+
test-case = "3.3.1"
24+
25+
[features]
26+
default = ["validation"]
27+
validation = []
2428

2529
[[bench]]
26-
name = "mutation_ends"
30+
name = "doubly_shuffling_around"
2731
harness = false

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2024 Ugur Arikan
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 390 additions & 217 deletions
Large diffs are not rendered by default.

benches/append.rs

Lines changed: 0 additions & 104 deletions
This file was deleted.

benches/doubly_iter.rs

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
2+
use orx_linked_list::*;
3+
use orx_selfref_col::MemoryPolicy;
4+
use rand::prelude::*;
5+
use rand_chacha::ChaCha8Rng;
6+
7+
#[derive(Clone)]
8+
enum Action {
9+
PushBack(String),
10+
PushFront(String),
11+
PopBack,
12+
PopFront,
13+
}
14+
15+
fn get_test_data(n: usize) -> Vec<Action> {
16+
let mut rng = ChaCha8Rng::seed_from_u64(56456);
17+
let mut vec: Vec<_> = (0..n)
18+
.map(|_| match rng.gen::<f32>() {
19+
x if x < 0.5 => Action::PushBack(rng.gen_range(0..n).to_string()),
20+
_ => Action::PushFront(rng.gen_range(0..n).to_string()),
21+
})
22+
.collect();
23+
for _ in 0..2 * n {
24+
let action = match rng.gen::<f32>() {
25+
x if x < 0.25 => Action::PushBack(rng.gen_range(0..n).to_string()),
26+
x if x < 0.50 => Action::PushFront(rng.gen_range(0..n).to_string()),
27+
x if x < 0.75 => Action::PopBack,
28+
_ => Action::PopFront,
29+
};
30+
vec.push(action)
31+
}
32+
vec
33+
}
34+
35+
// variants
36+
37+
fn fill_doubly_list<M: MemoryPolicy<Doubly<String>>>(
38+
actions: &[Action],
39+
list: &mut List<Doubly<String>, M>,
40+
) {
41+
for action in actions {
42+
match action {
43+
Action::PushBack(x) => {
44+
list.push_back(x.clone());
45+
}
46+
Action::PushFront(x) => {
47+
list.push_front(x.clone());
48+
}
49+
Action::PopBack => {
50+
_ = list.pop_back();
51+
}
52+
Action::PopFront => {
53+
_ = list.pop_front();
54+
}
55+
}
56+
}
57+
}
58+
59+
fn doubly_iter<M: MemoryPolicy<Doubly<String>>>(list: &List<Doubly<String>, M>) -> i64 {
60+
list.iter()
61+
.enumerate()
62+
.map(|(i, x)| match i % 2 {
63+
0 => x.len() as i64,
64+
_ => -(x.len() as i64),
65+
})
66+
.sum()
67+
}
68+
69+
fn doubly_iter_x<M: MemoryPolicy<Doubly<String>>>(list: &List<Doubly<String>, M>) -> i64 {
70+
list.iter_x()
71+
.enumerate()
72+
.map(|(i, x)| match i % 2 {
73+
0 => x.len() as i64,
74+
_ => -(x.len() as i64),
75+
})
76+
.sum()
77+
}
78+
79+
fn fill_std_linked_list(actions: &[Action], list: &mut std::collections::LinkedList<String>) {
80+
for action in actions {
81+
match action {
82+
Action::PushBack(x) => {
83+
list.push_back(x.clone());
84+
}
85+
Action::PushFront(x) => {
86+
list.push_front(x.clone());
87+
}
88+
Action::PopBack => {
89+
_ = list.pop_back();
90+
}
91+
Action::PopFront => {
92+
_ = list.pop_front();
93+
}
94+
}
95+
}
96+
}
97+
98+
fn std_linked_list(list: &std::collections::LinkedList<String>) -> i64 {
99+
list.iter()
100+
.enumerate()
101+
.map(|(i, x)| match i % 2 {
102+
0 => x.len() as i64,
103+
_ => -(x.len() as i64),
104+
})
105+
.sum()
106+
}
107+
108+
fn fill_vec_deque(actions: &[Action], list: &mut std::collections::VecDeque<String>) {
109+
for action in actions {
110+
match action {
111+
Action::PushBack(x) => {
112+
list.push_back(x.clone());
113+
}
114+
Action::PushFront(x) => {
115+
list.push_front(x.clone());
116+
}
117+
Action::PopBack => {
118+
_ = list.pop_back();
119+
}
120+
Action::PopFront => {
121+
_ = list.pop_front();
122+
}
123+
}
124+
}
125+
}
126+
127+
fn std_vec_deque(list: &std::collections::VecDeque<String>) -> i64 {
128+
list.iter()
129+
.enumerate()
130+
.map(|(i, x)| match i % 2 {
131+
0 => x.len() as i64,
132+
_ => -(x.len() as i64),
133+
})
134+
.sum()
135+
}
136+
137+
fn bench(c: &mut Criterion) {
138+
let treatments = vec![1_024 * 64 * 4];
139+
140+
let mut group = c.benchmark_group("doubly_iter");
141+
142+
for n in &treatments {
143+
let data = get_test_data(*n);
144+
145+
let mut std_list = std::collections::LinkedList::new();
146+
fill_std_linked_list(&data, &mut std_list);
147+
let expected = std_linked_list(&std_list);
148+
149+
group.bench_with_input(BenchmarkId::new("LinkedList", n), n, |b, _| {
150+
let mut std_list = std::collections::LinkedList::new();
151+
fill_std_linked_list(&data, &mut std_list);
152+
b.iter(|| {
153+
let result = std_linked_list(&std_list);
154+
assert_eq!(result, expected);
155+
})
156+
});
157+
158+
group.bench_with_input(BenchmarkId::new("VecDeque", n), n, |b, _| {
159+
let mut list = std::collections::VecDeque::new();
160+
fill_vec_deque(&data, &mut list);
161+
b.iter(|| {
162+
let result = std_vec_deque(&list);
163+
assert_eq!(result, expected);
164+
})
165+
});
166+
167+
group.bench_with_input(BenchmarkId::new("DoublyList", n), n, |b, _| {
168+
let mut list = DoublyList::new();
169+
fill_doubly_list(&data, &mut list);
170+
b.iter(|| {
171+
let result = doubly_iter(&list);
172+
assert_eq!(result, expected);
173+
})
174+
});
175+
176+
group.bench_with_input(BenchmarkId::new("DoublyList(x)", n), n, |b, _| {
177+
let mut list = DoublyList::new();
178+
fill_doubly_list(&data, &mut list);
179+
b.iter(|| {
180+
let _result = doubly_iter_x(&list);
181+
// assert_eq!(result, expected);
182+
})
183+
});
184+
}
185+
186+
group.finish();
187+
}
188+
189+
criterion_group!(benches, bench);
190+
criterion_main!(benches);

0 commit comments

Comments
 (0)