History

refactor

Sebastian Thiel committed 6 years ago

Commit deea36c1 parent 83a01022 files · +30 −30Browse files

Unified · Split

2 files
  1. git-odb/src/pack/tree/iter.rs +22 −22
  2. git-odb/src/pack/tree/mod.rs +8 −8
git-odb/src/pack/tree/iter.rs+22−22
@@ -1,14 +1,14 @@
1use crate::pack::tree::{Item, Tree};1use crate::pack::tree::{Item, Tree};
2 2
3/// All the unsafe bits to support parallel iteration with write access3/// All the unsafe bits to support parallel iteration with write access
4impl<D> Tree<D> {4impl<T> Tree<T> {
5 #[allow(unsafe_code)]5 #[allow(unsafe_code)]
6 /// SAFETY: Called from node with is guaranteed to not be aliasing with any other node.6 /// SAFETY: Called from node with is guaranteed to not be aliasing with any other node.
7 /// Note that we are iterating nodes that we are affecting here, but that only affects the7 /// Note that we are iterating nodes that we are affecting here, but that only affects the
8 /// 'is_root' field fo the item, not the data field that we are writing here.8 /// 'is_root' field fo the item, not the data field that we are writing here.
9 /// For all details see `from_node_take_entry()`.9 /// For all details see `from_node_take_entry()`.
10 unsafe fn from_node_put_data(&self, index: usize, data: D) {10 unsafe fn from_node_put_data(&self, index: usize, data: T) {
11 let items_mut: &mut Vec<Item<D>> = &mut *(self.items.get());11 let items_mut: &mut Vec<Item<T>> = &mut *(self.items.get());
12 items_mut.get_unchecked_mut(index).data = data;12 items_mut.get_unchecked_mut(index).data = data;
13 }13 }
14 14
@@ -22,11 +22,11 @@ impl<D> Tree<D> { · 7 unmodified lines
22 /// alias multiple nodes in the tree.22 /// alias multiple nodes in the tree.
23 /// It's safe for multiple threads to hold different chunks, as they are guaranteed to be non-overlapping and unique.23 /// It's safe for multiple threads to hold different chunks, as they are guaranteed to be non-overlapping and unique.
24 /// If the tree is accessed after iteration, it will panic as no mutation is allowed anymore, nor is24 /// If the tree is accessed after iteration, it will panic as no mutation is allowed anymore, nor is
25 unsafe fn from_node_take_entry(&self, index: usize) -> (D, Vec<usize>)25 unsafe fn from_node_take_entry(&self, index: usize) -> (T, Vec<usize>)
26 where26 where
27 D: Default,27 T: Default,
28 {28 {
29 let items_mut: &mut Vec<Item<D>> = &mut *(self.items.get());29 let items_mut: &mut Vec<Item<T>> = &mut *(self.items.get());
30 let item = items_mut.get_unchecked_mut(index);30 let item = items_mut.get_unchecked_mut(index);
31 let children = std::mem::take(&mut item.children);31 let children = std::mem::take(&mut item.children);
32 let data = std::mem::take(&mut item.data);32 let data = std::mem::take(&mut item.data);
@@ -35,11 +35,11 @@ impl<D> Tree<D> { · 2 unmodified lines
35 35
36 #[allow(unsafe_code)]36 #[allow(unsafe_code)]
37 /// SAFETY: As `take_entry(…)` - but this one only takes if the data of Node is a root37 /// SAFETY: As `take_entry(…)` - but this one only takes if the data of Node is a root
38 unsafe fn from_iter_take_entry_if_root(&self, index: usize) -> Option<(D, Vec<usize>)>38 unsafe fn from_iter_take_entry_if_root(&self, index: usize) -> Option<(T, Vec<usize>)>
39 where39 where
40 D: Default,40 T: Default,
41 {41 {
42 let items_mut: &mut Vec<Item<D>> = &mut *(self.items.get());42 let items_mut: &mut Vec<Item<T>> = &mut *(self.items.get());
43 let item = items_mut.get_unchecked_mut(index);43 let item = items_mut.get_unchecked_mut(index);
44 if item.is_root {44 if item.is_root {
45 let children = std::mem::take(&mut item.children);45 let children = std::mem::take(&mut item.children);
@@ -52,9 +52,9 @@ impl<D> Tree<D> { · 6 unmodified lines
52}52}
53 53
54/// Iteration54/// Iteration
55impl<D> Tree<D> {55impl<T> Tree<T> {
56 /// Return an iterator over chunks of roots. Roots are not children themselves, they have no parents.56 /// Return an iterator over chunks of roots. Roots are not children themselves, they have no parents.
57 pub fn iter_root_chunks(&mut self, size: usize) -> Chunks<D> {57 pub fn iter_root_chunks(&mut self, size: usize) -> Chunks<T> {
58 Chunks {58 Chunks {
59 tree: self,59 tree: self,
60 size,60 size,
@@ -63,18 +63,18 @@ impl<D> Tree<D> { · 2 unmodified lines
63 }63 }
64}64}
65 65
66pub struct Node<'a, D> {66pub struct Node<'a, T> {
67 tree: &'a Tree<D>,67 tree: &'a Tree<T>,
68 index: usize,68 index: usize,
69 children: Vec<usize>,69 children: Vec<usize>,
70 pub data: D,70 pub data: T,
71}71}
72 72
73impl<'a, D> Node<'a, D>73impl<'a, T> Node<'a, T>
74where74where
75 D: Default,75 T: Default,
76{76{
77 pub fn store_changes_then_into_child_iter(self) -> impl Iterator<Item = Node<'a, D>> {77 pub fn store_changes_then_into_child_iter(self) -> impl Iterator<Item = Node<'a, T>> {
78 #[allow(unsafe_code)]78 #[allow(unsafe_code)]
79 // SAFETY: The index is valid as it was controlled by `add_child(…)`, then see `take_entry(…)`79 // SAFETY: The index is valid as it was controlled by `add_child(…)`, then see `take_entry(…)`
80 unsafe {80 unsafe {
@@ -95,17 +95,17 @@ where · 14 unmodified lines
95 }95 }
96}96}
97 97
98pub struct Chunks<'a, D> {98pub struct Chunks<'a, T> {
99 tree: &'a Tree<D>,99 tree: &'a Tree<T>,
100 size: usize,100 size: usize,
101 cursor: usize,101 cursor: usize,
102}102}
103 103
104impl<'a, D> Iterator for Chunks<'a, D>104impl<'a, T> Iterator for Chunks<'a, T>
105where105where
106 D: Default,106 T: Default,
107{107{
108 type Item = Vec<Node<'a, D>>;108 type Item = Vec<Node<'a, T>>;
109 109
110 fn next(&mut self) -> Option<Self::Item> {110 fn next(&mut self) -> Option<Self::Item> {
111 if self.cursor == self.tree.one_past_last_seen_root {111 if self.cursor == self.tree.one_past_last_seen_root {
git-odb/src/pack/tree/mod.rs+8−8
@@ -21,18 +21,18 @@ pub use iter::{Chunks, Node}; · 20 unmodified lines
21 21
22pub mod from_offsets;22pub mod from_offsets;
23 23
24pub struct Item<D> {24pub struct Item<T> {
25 pub offset: u64,25 pub offset: u64,
26 is_root: bool,26 is_root: bool,
27 pub data: D,27 pub data: T,
28 // TODO: figure out average amount of children per node and use smallvec instead28 // TODO: figure out average amount of children per node and use smallvec instead
29 children: Vec<usize>,29 children: Vec<usize>,
30}30}
31/// A tree that allows one-time iteration over all nodes and their children, consuming it in the process,31/// A tree that allows one-time iteration over all nodes and their children, consuming it in the process,
32/// while being shareable among threads without a lock.32/// while being shareable among threads without a lock.
33/// It does this by making the run-time guarantee that iteration only happens once.33/// It does this by making the run-time guarantee that iteration only happens once.
34pub struct Tree<D> {34pub struct Tree<T> {
35 items: UnsafeCell<Vec<Item<D>>>,35 items: UnsafeCell<Vec<Item<T>>>,
36 last_added_offset: u64,36 last_added_offset: u64,
37 one_past_last_seen_root: usize,37 one_past_last_seen_root: usize,
38}38}
@@ -42,7 +42,7 @@ pub struct Tree<D> { · 3 unmodified lines
42#[allow(unsafe_code)]42#[allow(unsafe_code)]
43unsafe impl<T> Sync for Tree<T> {}43unsafe impl<T> Sync for Tree<T> {}
44 44
45impl<D> Tree<D> {45impl<T> Tree<T> {
46 pub fn with_capacity(num_objects: usize) -> Result<Self, Error> {46 pub fn with_capacity(num_objects: usize) -> Result<Self, Error> {
47 if num_objects == 0 {47 if num_objects == 0 {
48 return Err(Error::InvariantNonEmpty);48 return Err(Error::InvariantNonEmpty);
@@ -63,7 +63,7 @@ impl<D> Tree<D> { · 14 unmodified lines
63 }63 }
64 }64 }
65 65
66 pub fn add_root(&mut self, offset: u64, data: D) -> Result<(), Error> {66 pub fn add_root(&mut self, offset: u64, data: T) -> Result<(), Error> {
67 // SAFETY: Because we passed the assertion above which implies no other access is possible as per67 // SAFETY: Because we passed the assertion above which implies no other access is possible as per
68 // standard borrow check rules.68 // standard borrow check rules.
69 #[allow(unsafe_code)]69 #[allow(unsafe_code)]
@@ -79,7 +79,7 @@ impl<D> Tree<D> { · 9 unmodified lines
79 Ok(())79 Ok(())
80 }80 }
81 81
82 pub fn add_child(&mut self, base_offset: u64, offset: u64, data: D) -> Result<(), Error> {82 pub fn add_child(&mut self, base_offset: u64, offset: u64, data: T) -> Result<(), Error> {
83 // SAFETY: Because we passed the assertion above which implies no other access is possible as per83 // SAFETY: Because we passed the assertion above which implies no other access is possible as per
84 // standard borrow check rules.84 // standard borrow check rules.
85 #[allow(unsafe_code)]85 #[allow(unsafe_code)]
@@ -99,7 +99,7 @@ impl<D> Tree<D> { · 13 unmodified lines
99 Ok(())99 Ok(())
100 }100 }
101 101
102 pub fn into_items(self) -> Vec<Item<D>> {102 pub fn into_items(self) -> Vec<Item<T>> {
103 self.items.into_inner()103 self.items.into_inner()
104 }104 }
105}105}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t