如何做一个国产数据库

Posted qianbo_insist

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何做一个国产数据库相关的知识,希望对你有一定的参考价值。

一和二

如何做一个国产数据库一
如何做一个国产数据库二

1、数据结构重新定义

再次重新定义数据结构

typedef struct sdata
{
	uint32_t index;
	char vardata[128];
}sdata;

typedef struct sdata_index
{
	uint32_t index;
	uint32_t offset;
}sdata_index;


//增加的数据库上下文环境结构体
typedef struct db_context
{
	char v_tablename[256];
	sdata_index *v_index = NULL;
	uint32_t v_tindex = 0;
	uint32_t v_nindex = 0;
}db_context;

2、增删改查

此次增加了一个数据库的db_context 结构体,包含文件名称,索引内存保存,两个index的内存保存,在增加四个api函数,以前的函数变成工具,定义tool.h 和tool.cpp.

增加api.h 和api.cpp,增加四个函数声明:

int   Insert(void *data,db_context *v_context);
int   Delete(void *key, db_context *v_context);
int   Update(void *key, void *data, db_context *v_context);
void *Select(void *key, db_context *v_context);

今天实现Insert 函数,暂不测试,因为单元测试需要单独一个教程才行

xx xx xx xx | xx xx xx xx | xx xx xx xx – xx xx xx xx
4字节最大索引| 4字节当前索引 4bytes index 4bytes offset
data

*/
//2M的空间做索引
//uint32_t indext;//索引总长度
//uint32_t indexn;//索引长度,内容为x个索引 indexn <= indext

2.1 实现索引读的函数

#define INDEX_BYTES 2 * 1024 * 1024
//int index_num = INDEX_BYTES / sizeof(int) * 2; //max index number is 162144


sdata_index* bfile_read_index(const char * file, uint32_t &indext,uint32_t &indexn)
{
	size_t nr;
	indext = 0;
	indexn = 0;
	FILE * fp = fopen(file, "rb");
	if (fp == NULL)
		return NULL;
	//读取最大的index值容量
	nr = fread(&indext, sizeof(uint32_t), 1, fp);
	if (nr == 0)
	{
		fclose(fp);
		return NULL;
	}
	//读取存储的索引值
	nr = fread(&indexn, sizeof(uint32_t), 1, fp);
	if (nr == 0)
	{
		fclose(fp);
		return NULL;
	}

	//4字节索引号 4字节偏移地址
	uint8_t * index = (uint8_t*)malloc(indexn * sizeof(uint32_t) * 2);
	nr = fread(index, indexn * sizeof(uint32_t) * 2, 1, fp);
	if (nr == 0)
	{
		fclose(fp);
		free(index);
		return NULL;
	}
	return (sdata_index*)index;
}

2.2 实现初始化数据库的函数

该函数并不完整,等待完善,有很多需要注意的地方

int Initialize(const char *tname, db_context *context)
{

	if (context == NULL)
		return -1;
	strcpy(context->v_tablename,tname);

	if (context->v_index == NULL)
		context->v_index = bfile_read_index(
			tname,             /*filename*/
			context->v_tindex, 
			context->v_nindex
		);

	if (context->v_index == NULL)
		return -1;
	return 0;
}

2.3实现插入

整个增加的流程为:

打开数据库
初始化读取
读取上次索引信息
写入当次索引+偏移
写入索引量last+1
int Insert(void *data, db_context *context)
{
	if (context->v_nindex < context->v_tindex)
	{
		FILE * fp = fopen(context->v_tablename, "wb");
		if (fp == NULL)
			return -1;


		fpos_t pos = 4 + 4 + (context->v_nindex) * (8);
		fsetpos(fp, &pos);
		//int last_index = context->v_nindex - 1;
		uint32_t  indexlast = context->v_index[context->v_nindex - 1].index ;
		uint32_t  indexinsert = indexlast + 1;
		size_t n = fwrite(&indexinsert, sizeof(uint32_t), 1, fp);
		if (n != sizeof(uint32_t))
		{
			fclose(fp);
			return -1;
		}

		sdata *pdata = (sdata*)data;

		size_t vsize = sizeof(pdata->vardata);
		uint32_t datasize = vsize * indexlast;
		fpos_t offset = 4 + 4 + INDEX_BYTES + datasize;
		n = fwrite(&offset, sizeof(uint32_t), 1, fp);
		if (n != sizeof(uint32_t))
		{
			fclose(fp);
			return -1;
		}

		fsetpos(fp, &offset);
		n = fwrite(data, vsize, 1, fp);
		if (n != vsize)
		{
			fclose(fp);
			return -1;
		}
		fpos_t index = sizeof(uint32_t);
		fsetpos(fp, &index);
		uint32_t newnindex = context->v_nindex + 1;
		n = fwrite(&newnindex, sizeof(uint32_t), 1, fp);
		if (n != sizeof(int))
		{
			fclose(fp);
			return -1;
		}
		fclose(fp);
		return 0;
	}
	return -1;
}


int   Delete(void *key, db_context *v_context)
{

}
int   Update(void *key, void *data, db_context *v_context)
{

}
void *Select(void *key, db_context *v_context)
{

}

上面说了,先实现增加函数,其他先不实现,也不测试,单元测试需要一个严格的定义和测试用例,此次先为增加流程的初步代码实现,有待完善。

以上是关于如何做一个国产数据库的主要内容,如果未能解决你的问题,请参考以下文章

如何做一个国产数据库

订阅发布系统得解耦与冗余

如何做一个国产数据库

如何做一个国产数据库系统

如何做一个国产数据库

如何做一个国产数据库 hash一致性算法