当前位置: 首页 > news >正文

公司网站建设什么价格低跨境网站有哪些平台

公司网站建设什么价格低,跨境网站有哪些平台,郑州专门做网站,做国外直播网站有哪些目录 前言一、设计思路二、文件存储格式三、数据库操作3.1. 数据库结构3.2. 数据库初始化3.3. 插入3.4. 删除3.5. 修改3.6. 查询3.7. 清空 四、示例代码 前言 之前介绍了C语言实现AVL树#xff0c; 本文是对AVL树的一个简单应用#xff0c;在资源偏紧张的硬件设备中可以使用… 目录 前言一、设计思路二、文件存储格式三、数据库操作3.1. 数据库结构3.2. 数据库初始化3.3. 插入3.4. 删除3.5. 修改3.6. 查询3.7. 清空 四、示例代码 前言 之前介绍了C语言实现AVL树 本文是对AVL树的一个简单应用在资源偏紧张的硬件设备中可以使用如资源足够还是建议使用sqlite。 先把仓库地址贴一下:https://gitee.com/sauryniu/file-database 一、设计思路 简单的实现文件数据库需要考虑两个方面一个是数据的持久存储另一个是数据的快速操作(增删改查)。关于持久存储我们可以把数据存储到文件中快速操作的话则需要借助算法实现这里选择在内存中建立AVL树相对二叉树来说性能比较均衡又不像其他树那样复杂。 二、文件存储格式 文件头文件数据库头部用户自定义大小和数据结构可用于保存版本信息之类的数据。数据块个数类型为int最大4字节取决于操作系统位数。数据块用户真正保存的数据内容自定义大小和数据结构但是需要统一。 三、数据库操作 3.1. 数据库结构 封装结构对象方便操作。 struct _file_db {file_db_t* _this;void* _private_;/* func: 添加元素到文件数据库中para: db : 文件数据库指针ele : 要被添加的元素指针return:int : 0 : 失败 0 成功note:ele 传入的建议是非指针变量的地址如果使用的是指向动态内存的指针则用完后需自行释放资源 */int (*add)(file_db_t* db, void *ele);/* func: 通过键值删除指定键值对应的元素para: db : 文件数据库指针key : 元素对应的键值return:int : 0 : 失败 0 成功note:none. */int (*del)(file_db_t* db, int key);/* func: 根据键值编辑指定的元素para: db : 文件数据库指针key : 元素对应的键值ele 目标元素将替换给定键值所对应的元素的值return:int : 0 : 失败 0 成功note:ele 参数通过用户传入的获取键值的函数计算得到的键值需要和本函数传入键值 key 一致 */ int (*edit)(file_db_t* db, int key, void *ele);/* func: 根据键值查询文件数据库中的元素para: db : 文件数据库指针key : 元素的键值return:void* : NULL 查询失败 other 查询到的元素的指针note:none. */void* (*query)(file_db_t* db, int key);/* func: 写入文件数据库的文件头para: db : 文件数据库指针head : 写入的文件头指针return:int : 0 : 失败 0 成功note:none. */int (*write_head)(file_db_t* db, void* head);/* func: 读取文件数据库的文件头到指定内存中para: db : 文件数据库指针head : 读出的文件头指针return:int : 0 : 失败 0 成功note:none. */int (*read_head)(file_db_t* db, void* head);/* func: 返回文件数据库中的元素个数para: db : 文件数据库指针return:int : 0 : 失败 other 元素个数note:none. */int (*size)(file_db_t* db);/* func: 遍历文件数据库中的所有内容然后使用传入的函数指针对每个元素执行操作para: db : 文件数据库指针visit : 对元素操作的函数指针return:int : 0 : 失败 0 成功note:none. */int (*traverse)(file_db_t* db, void (*visit)(void*));/* func: 清除文件数据库内容但是保存文件头para: db : 文件数据库指针return:int : -1 : 失败 0 成功note:【重要】此函数不能与 file_db_destory 同时使用 */int (*clear)(file_db_t* db);/* func: 并释放文件数据库相关动态内存para: db : 文件数据库指针return:int : -1 : 失败 0 成功note:【重要】此函数不能与 file_db_destory 同时使用 */int (*free)(file_db_t* db);/* func: 销毁数据库文件并释放相关动态内存para: db : 文件数据库指针return:int : -1 : 失败 0 成功note:【重要】此函数不能与 file_db_free 同时使用 */int (*destory)(file_db_t* db); };3.2. 数据库初始化 初始化数据库传入数据库路径以及其他相关信息如果文件不存在会创建 /* func: 使用指定的文件初始化文件数据库para: path : 存放数据的文件所在路径 head_size : 头大小data_size : 数据块大小pf_hash_func 从数据块中获取key的哈希函数head 头数据return:file_db_t* : 文件数据库指针note:如果不再使用该数据库需要调用销毁函数释放内存【重要】保存的数据的数据类型大小必须是固定的 */ file_db_t* file_db_init(const char* path, int head_size, int data_size, int (*pf_hash_func)(void *), void* head);3.3. 插入 插入数据块时会先查询数据库中key是否存在不存在才插入。插入时先把数据块写到文件尾部然后更新数据块数量最后把数据更新到AVL树中。 /* func: 添加元素到文件数据库中para: db : 文件数据库指针ele : 要被添加的元素指针return:int : 0 : 失败 0 成功-4 内部错误-5 key已存在-6 内存不足-7 写入文件异常 note:ele 传入变量如果使用的是指向动态内存的指针则用完后需自行释放资源 */ static int file_db_add(file_db_t* db, void* ele) {file_db_private_t* _this get_private_member(db);if(NULL _this) return -4;if(NULL ! _this-m_tree-query_by_key(_this-m_tree-_this, _this-pf_get_ele_key(ele)))return -5;int res_code 0;file_db_record_t* record_data (file_db_record_t*)malloc(sizeof(file_db_record_t));if(NULL record_data)return -6;void* ele_memory malloc(_this-m_data_size);if(NULL ele_memory){free(record_data);return -6;}memcpy(ele_memory, ele, _this-m_data_size);pthread_mutex_lock(_this-m_file_db_mutex);FILE *db_fp fopen(_this-m_path, rb);if(NULL db_fp) {FILE_DB_LOG_DEBUG(open db file error);res_code -7;goto RUNTIME_ERROR;}fseek(db_fp, 0, SEEK_END);record_data-offset ftell(db_fp);record_data-db db;int write_len fwrite(ele_memory, 1, _this-m_data_size, db_fp);if(write_len ! _this-m_data_size) {FILE_DB_LOG_DEBUG(write ele error, write[%d] but [%d], _this-m_data_size, write_len);fclose(db_fp);res_code -7;goto RUNTIME_ERROR;}_this-m_data_cnt;FILE_DB_LOG_DEBUG(write cnt %d, key %d, _this-m_data_cnt, _this-pf_get_ele_key(ele));fseek(db_fp, _this-m_head_size, SEEK_SET);write_len fwrite(_this-m_data_cnt, 1, sizeof(int), db_fp);if(write_len ! sizeof(int)){FILE_DB_LOG_DEBUG(write cnt error);_this-m_data_cnt--;fclose(db_fp);truncate(_this-m_path, record_data-offset);res_code -9;goto RUNTIME_ERROR;}fflush(db_fp);fclose(db_fp);record_data-ele ele_memory;pthread_mutex_unlock(_this-m_file_db_mutex);return _this-m_tree-add(_this-m_tree-_this, (void *)record_data);RUNTIME_ERROR:free(ele_memory);free(record_data);pthread_mutex_unlock(_this-m_file_db_mutex);return res_code; }3.4. 删除 删除数据库块时会先找到该数据块在文件中的位置把文件尾部的第一个数据块复制到待删除的数据块所在位置然后把数据块数量减1最后在AVL树中把该数据块删除。 /* func: 通过键值删除指定键值对应的元素para: db : 文件数据库指针key : 元素对应的键值return:int : 0 : 失败 0 成功note:none. */ static int file_db_del(file_db_t* db, int key) {file_db_private_t* _this get_private_member(db);if(NULL _this) {FILE_DB_LOG_DEBUG(Filedatabase error!);return -2;}file_db_record_t* record_data _this-m_tree-query_by_key(_this-m_tree-_this, key);if(NULL record_data){FILE_DB_LOG_DEBUG(No such element. Del fail!);return -3;}pthread_mutex_lock(_this-m_file_db_mutex);FILE* db_fp fopen(_this-m_path, rb);if(NULL db_fp){pthread_mutex_unlock(_this-m_file_db_mutex);return -4;}if(record_data-offset _this-m_head_size sizeof(int) _this-m_data_size * (_this-m_data_cnt - 1)){fseek(db_fp, 0, SEEK_END);fseek(db_fp, -_this-m_data_size, SEEK_END);void* buff malloc(_this-m_data_size);if(1 ! fread(buff, _this-m_data_size, 1, db_fp)){FILE_DB_LOG_DEBUG(Read tail element error! file position %ld, ftell(db_fp));free(buff);fclose(db_fp);pthread_mutex_unlock(_this-m_file_db_mutex);return -5;}fseek(db_fp, record_data-offset, SEEK_SET);if(1 ! fwrite(buff, _this-m_data_size, 1, db_fp)){FILE_DB_LOG_DEBUG(Write tail element error!);free(buff);fclose(db_fp);pthread_mutex_unlock(_this-m_file_db_mutex);return -6;}free(buff);}_this-m_data_cnt--;fseek(db_fp, _this-m_head_size, SEEK_SET);int write_len fwrite(_this-m_data_cnt, sizeof(int), 1, db_fp);if(write_len ! 1){FILE_DB_LOG_DEBUG(write cnt error);_this-m_data_cnt;fclose(db_fp);pthread_mutex_unlock(_this-m_file_db_mutex);return -7;}fclose(db_fp);truncate(_this-m_path, _this-m_head_size sizeof(int) _this-m_data_cnt * _this-m_data_size );pthread_mutex_unlock(_this-m_file_db_mutex);return _this-m_tree-del_node_by_key(_this-m_tree-_this, key); }3.5. 修改 修改数据块需要传入数据块对应key值和数据块内容定位到文件中数据块位置后更新最后把AVL树中的数据更新一下就可以。 /* func: 根据键值编辑指定的元素para: db : 文件数据库指针key : 元素对应的键值ele 目标元素将替换给定键值所对应的元素的值return:int : 0 : 失败 0 成功note:ele 参数通过用户传入的获取键值的函数计算得到的键值需要和本函数传入键值 key 一致 */ static int file_db_edit(file_db_t* db, int key, void *ele) {file_db_private_t* _this get_private_member(db);if(NULL _this || NULL ele) return -1;if(key ! _this-pf_get_ele_key(ele)){FILE_DB_LOG_DEBUG(Edit error, Key value and element do not match);return -1;}pthread_mutex_lock(_this-m_file_db_mutex);file_db_record_t* record_data (file_db_record_t*)(_this-m_tree-query_by_key(_this-m_tree-_this, key));if(NULL record_data){FILE_DB_LOG_DEBUG(Edit error, Query data error);pthread_mutex_unlock(_this-m_file_db_mutex);return -2;}memset(record_data-ele, 0, _this-m_data_size);memcpy(record_data-ele, ele, _this-m_data_size);FILE_DB_LOG_DEBUG(query key[%d], ele key[%d], get key[%d], key, _this-pf_get_ele_key(ele), _this-pf_get_ele_key(record_data-ele));FILE* db_fp fopen(_this-m_path, rb);if(NULL db_fp) {FILE_DB_LOG_DEBUG(Edit error, File error);pthread_mutex_unlock(_this-m_file_db_mutex);return -3;}fseek(db_fp, record_data-offset, SEEK_SET);if(fwrite(record_data-ele, _this-m_data_size, 1, db_fp) ! 1){fclose(db_fp);pthread_mutex_unlock(_this-m_file_db_mutex);FILE_DB_LOG_DEBUG(Edit element, write new error!);return -4;}fclose(db_fp);pthread_mutex_unlock(_this-m_file_db_mutex);return 0; } 3.6. 查询 查询比较简单直接传入key在AVL树中查询即可。 /* func: 根据键值查询文件数据库中的元素para: db : 文件数据库指针key : 元素的键值return:void* : NULL 查询失败 other 查询到的元素的指针note:none. */ static void* file_db_query(file_db_t* db, int key) {file_db_private_t* _this get_private_member(db);if(NULL _this) {FILE_DB_LOG_DEBUG(_this is NULL);return NULL;}file_db_record_t* record_data (file_db_record_t*)(_this-m_tree-query_by_key(_this-m_tree-_this, key));if(NULL record_data) {FILE_DB_LOG_DEBUG(record_data is NULL);return NULL;}return record_data-ele; }3.7. 清空 清空时直接把文件截断然后把数据块数量写入0最后清空所有AVL树节点即可。 /* func: 清除文件数据库内容但是保存文件头para: db : 文件数据库指针return:int : -1 : 失败 0 成功note:【重要】此函数不能与 file_db_destory 同时使用 */ static int file_db_clear(file_db_t* db) {file_db_private_t* _this get_private_member(db);if(NULL _this) return -1;int cnt 0;pthread_mutex_lock(_this-m_file_db_mutex);FILE* db_fp fopen(_this-m_path, rb);if(NULL db_fp){pthread_mutex_unlock(_this-m_file_db_mutex);return -1;}fseek(db_fp, _this-m_head_size, SEEK_SET);if(1 ! fwrite(cnt, sizeof(int), 1, db_fp)){fclose(db_fp);pthread_mutex_unlock(_this-m_file_db_mutex);FILE_DB_LOG_DEBUG([file_db_clear] : write cnt error);return -2;} fclose(db_fp);truncate(_this-m_path, _this-m_head_size sizeof(int));pthread_mutex_unlock(_this-m_file_db_mutex);_this-m_data_cnt 0;_this-m_tree-clear_node(_this-m_tree-_this);return 0; }四、示例代码 示例代码使用名称为 example.db 的文件作为数据库文件采用随机数的方式最大写入20个元素通常会小于20个因为会有一部分重复的然后进行删、改、查的操作。 #include stdio.h #include string.h #include stdlib.h #include time.h #include FileDatabase.h#define EXAMPLE_FILE_DB example.db #define FILE_DB_SIZE 20 static file_db_t* file_db;typedef struct _db_head {int version;char reserve[252]; }db_head_t;typedef struct _db_data {int key;char value[60]; }db_data_t;static int get_key(void *ele) {if(NULL ele){return -1;}db_data_t* record (db_data_t*)ele;return record-key; }static void visit(void* ele) {if(NULL ele) {printf(ele null!!!);}db_data_t* data (db_data_t*)ele;printf([visit] key[%d]-value[%s]\r\n, data-key, data-value); }int main(void) {db_head_t head;head.version 1;file_db file_db_init(EXAMPLE_FILE_DB, sizeof(db_head_t), sizeof(db_data_t), get_key, head);if(NULL file_db){printf(create db error\r\n);return -1;}db_data_t element;int cnt 0;srand(time(NULL));int key[FILE_DB_SIZE];int index 0;for(int i 0; i FILE_DB_SIZE; i){int num rand()%FILE_DB_SIZE;key[index] num;//printf(index :%d - key %d\r\n, index, key[index]);element.key num;memset(element.value, 0, 60);sprintf(element.value, element%d, num);if(0 file_db-add(file_db-_this, element)){cnt;}}printf(Add cnt %d, total %d\r\n, cnt, file_db-size(file_db-_this));int random_key rand()%FILE_DB_SIZE;printf(Del key[%d], res[%d]\r\n, key[random_key], file_db-del(file_db-_this, key[random_key]));random_key rand()%FILE_DB_SIZE;memset(element.value, 0, 60);sprintf(element.value, edit%d, key[random_key]);element.key key[random_key];printf(Edit key[%d], res[%d]\r\n, key[random_key], file_db-edit(file_db-_this, key[random_key], element));random_key rand()%FILE_DB_SIZE;db_data_t* ele_query (db_data_t*) file_db-query(file_db-_this, key[random_key]);if(NULL ele_query){printf(ele_query null\r\n);}else{printf(Query key[%d], value[%s]\r\n, ele_query-key, ele_query-value);}file_db-traverse(file_db-_this, visit);file_db-clear(file_db-_this);file_db-free(file_db-_this);//file_db-destory(file_db-_this);return 0; }
http://www.zqtcl.cn/news/450345/

相关文章:

  • 宝山网站制作网站优化待遇
  • 网站建设项目竞争性招标文件界面设计的重要性
  • 网站建设合同机械设备网络推广方案
  • 阿里巴巴做网站的绿色的医疗资讯手机网站wap模板html源码下载
  • 怎么样自己做企业网站dz采集wordpress
  • 欧 美 做 爱 视频网站阿里巴巴电子商务网站建设目的
  • 动易网站后台修改栏目的字定制型网站设计价格
  • 设计网站页面临夏州建设厅官方网站
  • 给别人做网站需要什么许可证大连做网站开发的公司
  • 哪些网站国内打不开线下推广小组为了推广开放文明环境地图
  • 电子商务网站建设的核心网站收录检测
  • 厦门中小企业建网站补助源码做微信电影网站
  • 利用表单大师做网站网站备案证书放到哪里
  • 辽宁省建设科学研究院网站asp.net做网站 推荐书籍
  • 网站解决访问量超载做国外营销型网站设计
  • 思科中国网站开发案例网站如何进行建设
  • 网页设计与网站建设郑州大学怎么在传奇网站上做宣传
  • 中国建设银行重庆网站首页sns网站需求
  • 外网常用网站全网网站建设设计
  • 成都建设网站费用做数据库与网站招什么人
  • 最好的wordpress教程啥叫优化
  • 哪个网站做网销更好网站流量流出异常
  • 广州网站定做纸箱手工制作大全
  • 数据库修改网站后台密码cms三合一网站源码
  • 一般做哪些外贸网站丰南建设局网站
  • 网站如何被收录情况自己做的网站如何实现下载文件
  • 龙岩网站设计一般要多久深圳做自适应网站设计
  • 类似于拼多多的网站怎么做资料下载网站建设
  • 做商城网站哪里网站官网建设的价格
  • 网站怎么做用户体验山东富国建设投资有限公司网站