Skip to content

Commit

Permalink
Merge pull request #84 from cutsea110/retry-exercise-4.15-clock
Browse files Browse the repository at this point in the history
Exercise 4.15 Clock strategy (retry)
  • Loading branch information
cutsea110 authored Jul 27, 2022
2 parents ee80279 + 25e2754 commit d517249
Showing 1 changed file with 25 additions and 24 deletions.
49 changes: 25 additions & 24 deletions src/buffer/manager/clock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub struct ClockBufferMgr {
num_of_buffer_assigned: u32,
// extends by exercise 4.17
// Let only try_to_pin to handle this HashMap.
assigned_block_ids: HashMap<BlockId, Arc<Mutex<Buffer>>>,
assigned_block_ids: HashMap<BlockId, usize>,
// extends by exercise 4.14
clock_hands: usize,
}
Expand All @@ -48,60 +48,61 @@ impl ClockBufferMgr {
}
// TODO: fix for thread safe
fn try_to_pin(&mut self, blk: &BlockId) -> Result<Arc<Mutex<Buffer>>> {
let mut buff = self.find_existing_buffer(blk);
match buff {
let mut found = self.find_existing_buffer(blk);
match found {
Some(_) => {
// for statistics
self.num_of_cache_hits += 1;
}
None => {
let found = self.choose_unpinned_buffer();
found = self.choose_unpinned_buffer();
match found {
None => {
return Err(From::from(BufferMgrError::BufferAbort));
}
Some(b) => {
buff = Some(Arc::clone(&b));
// release blk
if let Some(blk) = buff.as_ref().unwrap().lock().unwrap().block() {
self.assigned_block_ids.remove(blk);
}
Some(i) => {
// add blk
self.assigned_block_ids
.insert(blk.clone(), Arc::clone(&buff.as_ref().unwrap()));
self.assigned_block_ids.insert(blk.clone(), i);

let mut b = self.bufferpool[i].lock().unwrap();
b.assign_to_block(blk.clone())?;
// for statistics
self.num_of_buffer_assigned += 1;
}
}

let mut b = buff.as_ref().unwrap().lock().unwrap();
b.assign_to_block(blk.clone())?;
// for statistics
self.num_of_buffer_assigned += 1;
}
}

let mut b = buff.as_ref().unwrap().lock().unwrap();
let i = found.unwrap();
let mut b = self.bufferpool[i].lock().unwrap();
if !b.is_pinned() {
*(self.num_available.lock().unwrap()) -= 1;
}
b.pin();

drop(b); // release lock
Ok(buff.unwrap())
Ok(Arc::clone(&self.bufferpool[i]))
}
fn find_existing_buffer(&self, blk: &BlockId) -> Option<Arc<Mutex<Buffer>>> {
self.assigned_block_ids.get(blk).map(|b| Arc::clone(b))
fn find_existing_buffer(&self, blk: &BlockId) -> Option<usize> {
self.assigned_block_ids.get(blk).map(|i| *i)
}
// The Clock Strategy
fn choose_unpinned_buffer(&mut self) -> Option<Arc<Mutex<Buffer>>> {
fn choose_unpinned_buffer(&mut self) -> Option<usize> {
let buffsize = self.bufferpool.len();

for i in self.clock_hands..self.clock_hands + buffsize {
let idx = i % buffsize;
if !self.bufferpool[idx].lock().unwrap().is_pinned() {
let buff = self.bufferpool[idx].lock().unwrap();
if !buff.is_pinned() {
// release blk
if let Some(blk) = buff.block() {
self.assigned_block_ids.remove(blk);
}

// Update the hands for the next time this function is called
self.clock_hands = idx + 1; // next call will start from after the replaced page.

return Some(Arc::clone(&self.bufferpool[idx]));
return Some(idx);
}
}

Expand Down

0 comments on commit d517249

Please sign in to comment.