Skip to content

Commit caedfa2

Browse files
committed
split ordered list, too hard
1 parent a752307 commit caedfa2

File tree

1 file changed

+48
-6
lines changed

1 file changed

+48
-6
lines changed

homework/src/hash_table/split_ordered_list.rs

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,22 @@ impl<V> SplitOrderedList<V> {
5353
&'s self,
5454
index: usize,
5555
guard: &'s Guard,
56-
) -> Cursor<'s, usize, MaybeUninit<V>> {
57-
todo!()
56+
) -> (Cursor<'s, usize, MaybeUninit<V>>, bool) {
57+
let index_ptr = self.buckets.get(index, guard);
58+
let bucket = index_ptr.load(SeqCst, guard);
59+
if bucket.is_null() {
60+
let new_v = MaybeUninit::uninit();
61+
self.list.harris_insert(index, new_v, guard);
62+
}
63+
let mut cursor = self.list.head(guard);
64+
match cursor.find_harris(&index, guard) {
65+
Ok(true) => (cursor, true),
66+
Ok(false) => (self.list.head(guard), false),
67+
Err(_) => {
68+
// If the cursor is not valid, we need to reinitialize it.
69+
(self.list.head(guard), false)
70+
}
71+
}
5872
}
5973

6074
/// Moves the bucket cursor returned from `lookup_bucket` to the position of the given key.
@@ -64,7 +78,8 @@ impl<V> SplitOrderedList<V> {
6478
key: &usize,
6579
guard: &'s Guard,
6680
) -> (usize, bool, Cursor<'s, usize, MaybeUninit<V>>) {
67-
todo!()
81+
let (cursor, found) = self.lookup_bucket(*key, guard);
82+
(self.size.load(SeqCst), found, cursor)
6883
}
6984

7085
fn assert_valid_key(key: usize) {
@@ -76,18 +91,45 @@ impl<V> ConcurrentMap<usize, V> for SplitOrderedList<V> {
7691
fn lookup<'a>(&'a self, key: &usize, guard: &'a Guard) -> Option<&'a V> {
7792
Self::assert_valid_key(*key);
7893

79-
todo!()
94+
match self.find(key, guard) {
95+
(_, true, cursor) => Some(unsafe { cursor.lookup().assume_init_ref() }),
96+
(_, false, _) => None,
97+
}
8098
}
8199

82100
fn insert(&self, key: usize, value: V, guard: &Guard) -> Result<(), V> {
83101
Self::assert_valid_key(key);
84102

85-
todo!()
103+
let (size, found, mut cursor) = self.find(&key, guard);
104+
if found {
105+
let old_value = unsafe { cursor.lookup().assume_init_read() };
106+
Err(old_value)
107+
} else {
108+
let new_value = MaybeUninit::new(value);
109+
if size * Self::LOAD_FACTOR <= self.count.load(SeqCst) {
110+
// Resize the buckets if necessary.
111+
self.lookup_bucket(size * 2, guard);
112+
}
113+
// Insert the new value into the list.
114+
self.list.harris_insert(key, new_value, guard);
115+
self.count.fetch_add(1, SeqCst);
116+
Ok(())
117+
}
86118
}
87119

88120
fn delete<'a>(&'a self, key: &usize, guard: &'a Guard) -> Result<&'a V, ()> {
89121
Self::assert_valid_key(*key);
90122

91-
todo!()
123+
let (size, found, mut cursor) = self.find(key, guard);
124+
if !found {
125+
return Err(());
126+
}
127+
// Remove the value from the list.
128+
if cursor.delete(guard).is_err() {
129+
// If the cursor is not valid, we need to reinitialize it.
130+
return Err(());
131+
}
132+
self.count.fetch_sub(1, SeqCst);
133+
Ok(unsafe { cursor.lookup().assume_init_ref() })
92134
}
93135
}

0 commit comments

Comments
 (0)