【cmu】

cmu15445-project1

project1

task1

//===----------------------------------------------------------------------===//
//
//                         BusTub
//
// lru_k_replacer.cpp
//
// Identification: src/buffer/lru_k_replacer.cpp
//
// Copyright (c) 2015-2022, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include "buffer/lru_k_replacer.h"
#include "common/exception.h"

namespace bustub {

LRUKReplacer::LRUKReplacer(size_t num_frames, size_t k) : replacer_size_(num_frames), k_(k) {}

auto LRUKReplacer::Evict(frame_id_t *frame_id) -> bool {
  std::lock_guard<std::mutex> guard(latch_);
  if (node_store_.empty()) {
    return false;
  }
  size_t max_distance = 0;
  bool found = false;
  frame_id_t candidate_frame_id = -1;

  for (auto &pair : node_store_) {
    const auto &node = pair.second;
    if (!node.is_evictable_) {
      continue;
    }
    size_t distance;
    if (node.history_.size() < k_) {
      distance = std::numeric_limits<size_t>::max();  // 少于 k 次访问视为无穷大
    } else {
      distance = current_timestamp_ - node.history_.front();
    }

    if (distance > max_distance) {
      max_distance = distance;
      candidate_frame_id = pair.first;
      found = true;
    } else if (distance == max_distance && candidate_frame_id > pair.first) {
      // 在后向 k 距离相同的情况下,选择帧 ID 更小的帧(即最近最少使用的帧)
      candidate_frame_id = pair.first;
    }
  }

  if (found) {
    node_store_.erase(candidate_frame_id);
    *frame_id = candidate_frame_id;
    curr_size_--;
    return true;
  }

  return false;
}

void LRUKReplacer::RecordAccess(frame_id_t frame_id, [[maybe_unused]] AccessType access_type) {
  std::lock_guard<std::mutex> guard(latch_);
  if (node_store_.find(frame_id) == node_store_.end()) {
    LRUKNode new_node;
    new_node.k_ = k_;  // 假设k_是LRUKNode需要的参数之一
    // 可能还需要设置其他LRUKNode的初始值
    node_store_[frame_id] = new_node;
  }

  current_timestamp_++;
  auto &node = node_store_[frame_id];
  if (node.history_.size() >= k_) {
    node.history_.pop_front();
  }
  node.history_.push_back(current_timestamp_);
}

void LRUKReplacer::SetEvictable(frame_id_t frame_id, bool set_evictable) {
  std::lock_guard<std::mutex> guard(latch_);
  if (node_store_.find(frame_id) == node_store_.end()) {
    throw Exception("Frame ID is invalid");
  }

  auto &node = node_store_[frame_id];
  if (node.is_evictable_ != set_evictable) {
    node.is_evictable_ = set_evictable;
    curr_size_ += set_evictable ? 1 : -1;
  }
}

void LRUKReplacer::Remove(frame_id_t frame_id) {
  std::lock_guard<std::mutex> guard(latch_);
  if (node_store_.find(frame_id) == node_store_.end()) {
    return;
  }
  auto &node = node_store_[frame_id];
  if (!node.is_evictable_) {
    throw Exception("Frame is not evictable");
  }

  node_store_.erase(frame_id);
  curr_size_--;
}

auto LRUKReplacer::Size() -> size_t {
  std::lock_guard<std::mutex> guard(latch_);
  return curr_size_;
}

}  // namespace bustub

task2

//===----------------------------------------------------------------------===//
//
//                         BusTub
//
// disk_scheduler.cpp
//
// Identification: src/storage/disk/disk_scheduler.cpp
//
// Copyright (c) 2015-2023, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include "storage/disk/disk_scheduler.h"
#include "common/exception.h"
#include "storage/disk/disk_manager.h"

namespace bustub {

DiskScheduler::DiskScheduler(DiskManager *disk_manager) : disk_manager_(disk_manager) {
  // Spawn the background thread
  background_thread_.emplace([&] { StartWorkerThread(); });
}

DiskScheduler::~DiskScheduler() {
  // Put a `std::nullopt` in the queue to signal to exit the loop
  request_queue_.Put(std::nullopt);
  if (background_thread_.has_value()) {
    background_thread_->join();
  }
}

void DiskScheduler::Schedule(DiskRequest r) {
  // 创建 promise 并获取对应的 future
  request_queue_.Put(std::make_optional(std::move(r)));
}

void DiskScheduler::StartWorkerThread() {
  while (true) {
    auto request_opt = request_queue_.Get();
    // 检查是否应该停止线程
    if (!request_opt.has_value()) {
      break;
    }
    // 处理磁盘请求
    DiskRequest &request = request_opt.value();
    if (request.is_write_) {
      disk_manager_->WritePage(request.page_id_, request.data_);
    } else {
      disk_manager_->ReadPage(request.page_id_, request.data_);
    }

    // 设置回调标志
    request.callback_.set_value(true);
  }
}

}  // namespace bustub

task3

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值