Files
BH-Bookstore-2023/docs/homework_requirement/memoryriver.hpp
2023-11-28 13:50:11 +00:00

126 lines
4.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifndef BPT_MEMORYRIVER_HPP
#define BPT_MEMORYRIVER_HPP
#include <fstream>
#include <iostream>
#include <stack>
using std::fstream;
using std::ifstream;
using std::ofstream;
using std::string;
template <class T, const int info_len = 2>
class MemoryRiver {
private:
/* your code here */
fstream file;
string file_name;
const int sizeofT = sizeof(T);
std::stack<int> free_mem;
int total_mem = 0;
public:
MemoryRiver() = default;
~MemoryRiver() {
file.open(file_name, std::ios::binary | std ::ios::out | std::ios::in);
file.seekp(info_len * sizeof(int), std::ios::beg);
// std::cerr << "pos1 " << info_len * sizeof(int) << std::endl;
file.write(reinterpret_cast<char *>(&total_mem), sizeof(int));
int tmp = free_mem.size();
file.write(reinterpret_cast<char *>(&tmp), sizeof(int));
file.seekp((info_len + 2) * sizeof(int) + total_mem * sizeofT,
std::ios::beg);
// std::cerr << "pos2 " << (info_len + 2) * sizeof(int) + total_mem * sizeofT
// << std::endl;
while (!free_mem.empty()) {
tmp = free_mem.top();
file.write(reinterpret_cast<char *>(&tmp), sizeof(int));
free_mem.pop();
}
file.close();
}
bool operator=(const MemoryRiver &) = delete;
MemoryRiver(const string &file_name) : file_name(file_name) {
file.open(file_name, std::ios::binary | std ::ios::out | std::ios::in);
file.seekg(info_len * sizeof(int), std::ios::beg);
file.read(reinterpret_cast<char *>(&total_mem), sizeof(int));
int free_mem_size = 0;
file.read(reinterpret_cast<char *>(&free_mem_size), sizeof(int));
file.seekg((info_len + 2) * sizeof(int) + total_mem * sizeofT,
std::ios::beg);
while (free_mem_size-- > 0) {
int tmp;
file.read(reinterpret_cast<char *>(&tmp), sizeof(int));
free_mem.push(tmp);
fprintf(stderr,"get %d\n",tmp);
}
file.close();
}
void initialise(string FN = "") {
if (FN != "") file_name = FN;
file.open(file_name, std::ios::binary | std ::ios::out);
file.seekp(0, std::ios::beg);
int tmp = 0;
for (int i = 0; i < info_len; ++i)
file.write(reinterpret_cast<char *>(&tmp), sizeof(int));
file.close();
}
// 读出第n个int的值赋给tmp1_base
void get_info(int &tmp, int n) {
if (n > info_len) return;
file.open(file_name, std::ios::binary | std ::ios::out | std::ios::in);
file.seekg((n - 1) * sizeof(int), std::ios::beg);
// std::cerr << "pos " << (n - 1) * sizeof(int) << std::endl;
file.read(reinterpret_cast<char *>(&tmp), sizeof(int));
file.close();
}
// 将tmp写入第n个int的位置1_base
void write_info(int tmp, int n) {
if (n > info_len) return;
file.open(file_name, std::ios::binary | std ::ios::out | std::ios::in);
file.seekp((n - 1) * sizeof(int), std::ios::beg);
file.write(reinterpret_cast<const char *>(&tmp), sizeof(int));
file.close();
}
// 在文件合适位置写入类对象t并返回写入的位置索引index
// 位置索引意味着当输入正确的位置索引index在以下三个函数中都能顺利的找到目标对象进行操作
int write(T &t) {
int index = -1;
if (!free_mem.empty()) {
index = free_mem.top();
free_mem.pop();
} else
index = ++total_mem;
update(t, index);
return index;
}
// 用t的值更新位置索引index对应的对象保证调用的index都是由write函数产生
void update(T &t, const int index) {
file.open(file_name, std::ios::binary | std ::ios::out | std::ios::in);
file.seekp((info_len + 2) * sizeof(int) + (index - 1) * sizeofT,
std::ios::beg);
file.write(reinterpret_cast<char *>(&t), sizeofT);
file.close();
}
// 读出位置索引index对应的T对象的值并赋值给t保证调用的index都是由write函数产生
void read(T &t, const int index) {
file.open(file_name, std::ios::binary | std ::ios::out | std::ios::in);
file.seekg((info_len + 2) * sizeof(int) + (index - 1) * sizeofT,
std::ios::beg);
file.read(reinterpret_cast<char *>(&t), sizeofT);
file.close();
}
// 删除位置索引index对应的对象(不涉及空间回收时,可忽略此函数)保证调用的index都是由write函数产生
void Delete(int index) { free_mem.push(index); }
};
#endif // BPT_MEMORYRIVER_HPP