首页 > 系统相关 >c++虚拟内存

c++虚拟内存

时间:2023-02-03 21:57:12浏览次数:39  
标签:return name pos len c++ file buf 虚拟内存

可以通过调用vmemalloc类型对象的括号运算符(len, name)分配大小为len,文件名为name的虚拟内存。
返回首地址的迭代器。
无需delete,程序结束后会自动清空文件,但是保留文件名

#include<bits/stdc++.h>
using namespace std;
namespace virtual_memory{
	/** 
	 * small functions to be called by filename.
	*/
	void file_reset(string fname, size_t siz){
		ofstream f(fname.c_str(), ios::binary| ios::out | ios::trunc);
		char val =0;
		for(int i = 0; i < siz; ++i) f.write(&val, 1);
		f.close();
	}
	void file_clear(string fname){
		file_reset(fname, 0);
	}
	/**
	 * proxy of a file.
	 * fixed file size.
	 * if a file was opened, the name won't be change.
	 * only opened by a file.
	 * safe write/read
	*/
	struct proxy_file{
		string fname;
		fstream f;
		size_t fsize;
		using pos_type = fstream :: pos_type;
		using off_type = fstream :: off_type;
		using seekdir = fstream :: seekdir;
		proxy_file(){
			fsize = 0;
		}
		proxy_file(string str, size_t siz) : proxy_file(){
			open(str, siz);
		}
		~proxy_file(){
			file_clear(fname);
		}
		void open(string str, size_t siz){
			assert(fname.empty() || str == fname);
			fname = str;
			fsize = siz;
			file_reset(str, siz);
			f.open(fname, ios :: binary | ios::out | ios::in);
			assert(f.good());
		}
		void write_at(const char* str, size_t siz, off_type pos){
			assert(0 <= pos && pos + siz <= fsize);
			// cerr << "bef = " << f.tellp() << endl;
			f.seekp(pos, ios :: beg);
			// cerr << "fat = " << f.tellp() << endl;
			f.write(str, siz);
		}
		void read_at(char * str, size_t siz, off_type pos){
			assert(0 <= pos && pos + siz <= fsize);
			f.seekg(pos, ios :: beg);
			f.read(str, siz);
		}
	};
	/**
	 * a pointer with a full information to read/write the file.
	 * with operator +, -, and so on.
	 * only check whether in the same file. uncheck the range.
	*/
	struct file_pointer{
		proxy_file* file;
		proxy_file :: off_type pos; 
		file_pointer()   {
			file = nullptr;
			pos = 0;
		}
		file_pointer(proxy_file* file_, proxy_file :: off_type pos_) : file(file_), pos(pos_){}
		friend ptrdiff_t operator - (const file_pointer& x, const file_pointer& y){
			assert(x.file == y.file);
			return x.pos - y.pos;
		}
		friend file_pointer operator + (file_pointer x, ptrdiff_t len){
			x.pos += len;
			return x;
		}
		friend file_pointer operator - (file_pointer x, ptrdiff_t len){
			x.pos -= len;
			return x;
		}
	};
	/**
	 * a proxy to the proxy_file
	 * because random access is very slow, we have to accelerate it by buffer
	 * safe read/write
	 * safe bounds
	*/
	const int FBUF_SIZE = 2;
	struct file_buf{
		char buf[FBUF_SIZE];
		file_pointer first; ptrdiff_t len;
		file_buf(){
			len = 0;
			memset(buf,0, sizeof(buf));
		}
		~file_buf(){
			write_through();
		}
		bool check_in(file_pointer p){
			assert(p.file != nullptr);
			return first.file == p.file && first.pos <= p.pos && p.pos < first.pos + len;
		}
		void write_through(){
			if(first.file == nullptr) return;
			first.file->write_at(buf, len, first.pos);
		}
		void read_through(){
			if(first.file == nullptr) return;
			first.file->read_at(buf, len, first.pos);
		}
		void init_buf(file_pointer p){
			if(check_in(p)) return;
			write_through();
			assert(p.pos < (p.file->fsize));
			first.file = p.file;
			first.pos = p.pos - FBUF_SIZE / 2 <  0 ? 0 : p.pos - FBUF_SIZE / 2;
			len = min(FBUF_SIZE, int(p.file->fsize - first.pos));
			read_through();
		}
		size_t get_pos(file_pointer p){
			init_buf(p);
			return p.pos - first.pos;
		}
		void read(file_pointer p, char& val){
			size_t pos = get_pos(p);
			val = buf[pos];
		}
		void write(file_pointer p, char val){
			size_t pos = get_pos(p);
			buf[pos] = val;
		}
	};

	struct file_view{
		file_buf * buf;
		file_pointer pos;
		file_view(){
			buf = nullptr;
		}
		file_view(file_buf * buf_, file_pointer pos_) : buf(buf_), pos(pos_) {};
		void read(char &val){
			assert(buf != nullptr);
			buf->read(pos, val);
		}
		void write(char val){
			assert(buf != nullptr);
			buf->write(pos, val);
		}
		friend auto operator - (const file_view& x, const file_view& y){
			assert(x.buf == y.buf);
			return x.pos - y.pos;
		}
		friend file_view operator + (file_view x, ptrdiff_t len){
			x.pos = x.pos +  len;
			return x;
		}
		friend file_view operator - (file_view x, ptrdiff_t len){
			x.pos = x.pos- len;
			return x;
		}	
	};
	struct proxy_char{
		file_view f;
		proxy_char(file_view f_) : f(f_){}
		proxy_char& operator = (char val){
			f.write(val);
			return *this;
		}
		operator char(){
			char val;
			f.read(val);
			return val;
		}
	};
	struct file_iterator{
		file_view f;
		file_iterator(file_view f_) : f(f_){}
		file_iterator(file_buf * buf_, file_pointer pos_) : file_iterator(file_view(buf_, pos_)) {
		}
		using iterator_category = random_access_iterator_tag;
		using difference_type = ptrdiff_t;
		using value_type = char;
		using pointer = proxy_char*;
		using reference = proxy_char&;
		friend auto operator - (const file_iterator& x, const file_iterator& y){
			return x.f - y.f;
		}
		friend file_iterator operator + (file_iterator x, ptrdiff_t len) {
			x.f = x.f + len;
			return x;
		}
		friend file_iterator operator - (file_iterator x, ptrdiff_t len) {
			x.f = x.f- len;
			return x;
		}
		file_iterator& operator += (ptrdiff_t len){
			*this = *this + len;
			return *this;
		}
		file_iterator& operator -= (ptrdiff_t len){
			*this = *this - len;
			return *this;
		}
		void operator ++(){
			*this = *this + 1;
		}
		void operator --(){
			*this = *this - 1;
		}
		proxy_char operator *(){
			return proxy_char(f);
		}
	};
	struct proxy_file_pool{
		map<string, proxy_file> data;
		proxy_file* get_file(string name){
			assert(data.count(name));
			return &data[name];
		}
		void create_file(string name, size_t siz){
			assert(data.count(name) == false);
			data[name].open(name, siz);
		}
		bool check_file(string name){
			return data.count(name);
		}
		void erase_file(string name){
			data.erase(name);
		}
	};
	struct vmemalloc{
		proxy_file_pool	pool;
		file_buf buf;
		file_iterator operator ()(size_t len, string name){
			pool.create_file(name, len);
			return file_iterator(&buf, file_pointer(pool.get_file(name), 0));
		}
	};
}
using virtual_memory :: vmemalloc;
vmemalloc newnode;
const int N = 1e2+1;
auto npri = newnode(N, "1.txt");
int pri[N] = {};
void sieve(int len){
	for(int i = 2; i <= len; ++i){
		if(*(npri + i) == false) pri[++pri[0]] = i;
		for(int j = 1; j <= pri[0] && i * pri[j] <= len; ++j){
			*(npri + i * pri[j]) = true;
			if(i % pri[j] == 0) break;
		}
	}
}
int main(){
	sieve(100);
	for(int i = 1; i <= pri[0]; ++i){
		cout << pri[i] <<" ";
	}
	cout << endl;
	return 0;
}

标签:return,name,pos,len,c++,file,buf,虚拟内存
From: https://www.cnblogs.com/cdsidi/p/17090510.html

相关文章

  • 代码随想录-数组-C++总结
    1.二分查找重点区分左闭右开,左闭右闭两种写法中的差异,理解循环中的不变量,这样在returnr还是l和什么时候l+1r-1什么时候不需要+1-1很重要。35.搜索插入位置-力扣(Leet......
  • C++ 1398:短信计费
    1398:短信计费【题目描述】用手机发短信,一条短信资费为0.1元,但限定一条短信的内容在70个字以内(包括70个字)。如果你一次所发送的短信超过了70个字,则会按照每70个字一条......
  • C++1155:回文三位数
    1155:回文三位数【题目描述】如果一个数从左边读和从右边读都是同一个数,就称为回文数。例如6886就是一个回文数,求出所有的既是回文数又是素数的三位数。【输入】(......
  • C++开发面试题合集
    1.epoll的工作原理(【360实习】C++开发)epoll是一种I/O事件通知机制,是linux内核实现IO多路复用的一个实现。在一个操作里同时监听多个输入输出源,在其中一个或多个输入输出......
  • C++ 哈希表查询_进入哈希函数结界的世界
    1.前言哈希表或称为散列表,是一种常见的、使用频率非常高的数据存储方案。哈希表属于抽象数据结构,需要开发者按哈希表数据结构的存储要求进行API定制,对于大部分高级语言......
  • C++第四章类与对象
    一、面向对象的基本特点1.  抽象对同一类对象的共同属性和行为进行概括,形成类。先注意问题的本质及描述,其次是实现过程或细节。数据抽象:描述某类对象的属性或状态(对象相互......
  • 【八大数据排序法】希尔排序法的图形理解和案例实现 | C++
    第十七章希尔排序法:::hljs-center目录第十七章希尔排序法●前言●认识排序●一、希尔排序法是什么?1.简要介绍2.图形理解3.算法分析●二、案例实现1.......
  • c++中调用QML中的函数和设置QML中的属性的问题
    1.这里主要是介绍,如何在c++中调用QML中的函数和设置QML中的属性的问题  2.具体代码    //UICtest.qmlimportQt4.7Rectangle{   id:mainWid......
  • C/C++编译链接
    一、编译链接过程名词解释编译:由编译器对各个源文件进行词法分析、语法分析、语义分析等操作,最终生成多个目标文件。由于这些文件可能存在互相调用对方的函数或变量,还......
  • 现代C++实战30讲
    本文记录学习吴咏炜老师的《现代C++实战》课程的心得体会,记录自认为值得记录的知识点。重新认识的点如果临时对象被绑定到一个引用上,则它的生命周期会延长到跟这个引用......