You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

128 lines
3.0 KiB

//
// Created by 马也驰 on 2025/1/4.
//
#ifndef LEVELDB_VLOG_CACHE_H
#define LEVELDB_VLOG_CACHE_H
#include <cassert>
#include <mutex>
#include <string>
#define BLOCK_SIZE 4096
struct frame_info {
std::mutex info_latch_;
bool used;
std::string vlog_name;
size_t vlog_block_num;
bool is_dirty;
inline void set_used() {
info_latch_.lock();
assert(used == false);
used = true;
info_latch_.unlock();
}
inline void set_unused() {
info_latch_.lock();
assert(used == true);
used = false;
info_latch_.unlock();
}
inline void set_dirty() {
info_latch_.lock();
assert(is_dirty == false);
is_dirty = true;
info_latch_.unlock();
}
inline void set_nondirty() {
info_latch_.lock();
assert(is_dirty == true);
is_dirty = false;
info_latch_.unlock();
}
inline void set_vlog_block_num(size_t vb) {
info_latch_.lock();
vlog_block_num = vb;
info_latch_.unlock();
}
inline void set_vlog_name(std::string &vn) {
info_latch_.lock();
vlog_name = vn;
info_latch_.unlock();
}
inline bool cache_hit(std::string &vn, size_t vbn) {
return used && (vlog_name == vn) && (vlog_block_num == vbn);
}
};
struct block_frame {
// 读,写,块置换 必须对这个mutex上锁,保证线性化
// 读写必须对这个mutex上锁,保证线性化
std::mutex mtx;
frame_info frame_info_;
char *block_buff;
block_frame() {
frame_info_.used = false;
frame_info_.is_dirty = false;
block_buff = static_cast<char*>(malloc(BLOCK_SIZE));
}
void free_block_buff() {
free(block_buff);
}
};
class VlogCache {
#define BLOCK_NUMS 1024
#define VALUE_ACROSS_BLOCK(offset, len) (((offset)/BLOCK_SIZE) != (((offset)+(len)-1)/BLOCK_SIZE))
#define DATA_SIZE_MASK 0x7fff
#define DATA_DELE_MASK 0x8000
public:
VlogCache() {
for (auto i = 0; i < BLOCK_NUMS; i++) {
block_frames[i] = new block_frame();
}
}
~VlogCache() {
flush_all_blocks();
for (auto i = 0; i < BLOCK_NUMS; i++) {
block_frames[i]->free_block_buff();
}
}
public:
void read_data(std::string &vlog_name, std::string& value, size_t offset, size_t len);
void write_data(std::string &vlog_name, std::string& value, size_t offset, size_t len);
uint16_t delete_data(std::string &vlog_name, size_t offset);
private:
void read_data_inblock(std::string &vlog_name, std::string& value, size_t offset, size_t len);
void write_data_inblock(std::string &vlog_name, std::string& value, size_t offset, size_t len);
void write_back_block(size_t block_num);
void read_in_block(size_t block_num, std::string &vlog_name, size_t vlog_block_num);
private:
void flush_all_blocks();
inline size_t offset_2_blocknum(size_t offset) {
return (offset / BLOCK_SIZE) % BLOCK_NUMS;
}
inline size_t offset_2_inblock_offset(size_t offset) {
return offset % BLOCK_SIZE;
}
private:
block_frame *block_frames[BLOCK_NUMS];
};
#endif // LEVELDB_VLOG_CACHE_H