首先,我看完整个目录结构之后,我打算从sqlite的数据结构开始看起。
hash.h中定义了两个数据结构,Hash类包含以下成员

struct Hash {char keyClass;          /* 指示该hash是针对哪种基本类型而设置的,其设定4种 SQLITE_HASH_INT, _POINTER, _STRING, _BINARY */char copyKey;           /* 判断每个元素是否需要深复制,如pointer类型、binary类型都需要*/int count;              /*哈希表中的总元素个数*/HashElem *first;        /*哈希目录的首地址*/void *(*xMalloc)(int);  /*动态分配的函数指针*/void (*xFree)(void *);  /*释放内存的函数指针*/int htsize;             /* 桶的个数 */struct _ht {            /* 哈希桶*/int count;               /* 该桶的元素个数 */HashElem *chain;         /* 该桶的首指针 */} *ht;
};

其中copyKey判断HashElem类中的键指针是否需要深复制。
HashElem类包含以下成员

struct HashElem {HashElem *next, *prev;   /* 桶中指向下一个及前一个的指针 */void *data;              /* 存储的内容 */void *pKey; int nKey;    /* pKey指键内容,nKey指键长度 */
};

其中data并没有动态分配内存,而单纯是一个指针。
hash.c除了添加、查找、移除函数之外,还添加了几个比较函数,及哈希函数。

static int binHash(const void *pKey, int nKey);
static int binCompare(const void *pKey1, int n1, const void *pKey2, int n2);
static int strHash(const void *pKey, int nKey);
static int strCompare(const void *pKey1, int n1, const void *pKey2, int n2);
static int ptrHash(const void *pKey, int nKey);
static int ptrCompare(const void *pKey1, int n1, const void *pKey2, int n2);
static int intHash(const void *pKey, int nKey);
static int intCompare(const void *pKey1, int n1, const void *pKey2, int n2);

除了这些函数之外,他还给了两个函数,以保证使用Hash类的用户不用考虑调用哪个函数问题,实现更好的封装性。

static int (*compareFunction(int keyClass))(const void*,int,const void*,int);//通过判断keyClass,返回一个比较函数指针
static int (*hashFunction(int keyClass))(const void*,int);//通过判断keyClass,返回一个hash函数指针

这里的hash结构写的非常简洁易懂,还实现较好的封装性,并同时不用声明不同类型的hash结构,直接使用一个变量keyclass及void *完美解决该问题。
用c++实现应该可以用函数模版来解决该问题。

sqlite源码剖析(一)相关推荐

  1. SQLite源码编译教程

    SQLite源码编译安装 SQLite简介 编译安装 源码下载 编译过程 demo实例 总结 SQLite简介 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页.如果你想学习如何使用M ...

  2. 老李推荐:第14章4节《MonkeyRunner源码剖析》 HierarchyViewer实现原理-装备ViewServer-端口转发 1...

    老李推荐:第14章4节<MonkeyRunner源码剖析> HierarchyViewer实现原理-装备ViewServer-端口转发 在初始化HierarchyViewer的实例过程中, ...

  3. JS魔法堂:mmDeferred源码剖析

    一.前言 avalon.js的影响力愈发强劲,而作为子模块之一的mmDeferred必然成为异步调用模式学习之旅的又一站呢!本文将记录我对mmDeferred的认识,若有纰漏请各位指正,谢谢.项目请见 ...

  4. Kafka源码剖析 —— 网络I/O篇 —— 浅析KafkaSelector

    为什么80%的码农都做不了架构师?>>>    ##NioSelector和KafkaSelector有什么区别? 先说结论,KafkaSelector(org.apache.kaf ...

  5. Mongoose源码剖析:Introduction and Installation

    引言 要剖析Mongoose的源码,首先你得知道它的一些基本情况和特性.并去使用它.本文就是介绍Mongoose是个什么东西?及如何安装和使用?这里假设你知道什么web服务器软件.web服务器使用什么 ...

  6. 老李推荐:第5章5节《MonkeyRunner源码剖析》Monkey原理分析-启动运行: 获取系统服务引用 1...

    老李推荐:第5章5节<MonkeyRunner源码剖析>Monkey原理分析-启动运行: 获取系统服务引用 上一节我们描述了monkey的命令处理入口函数run是如何调用optionPro ...

  7. 老李推荐:第3章3节《MonkeyRunner源码剖析》脚本编写示例: MonkeyImage API使用示例 1...

    老李推荐:第3章3节<MonkeyRunner源码剖析>脚本编写示例: MonkeyImage API使用示例 在上一节的第一个"增加日记"的示例中,我们并没有看到日记 ...

  8. Mongoose源码剖析:外篇之web服务器

    引言 在深入Mongoose源码剖析之前,我们应该清楚web服务器是什么?它提供什么服务?怎样提供服务?使用什么协议?客户端如何唯一标识web服务器的资源?下面我们抛开Mongoose,来介绍一个we ...

  9. STL源码剖析学习七:stack和queue

    STL源码剖析学习七:stack和queue stack是一种先进后出的数据结构,只有一个出口. 允许新增.删除.获取最顶端的元素,没有任何办法可以存取其他元素,不允许有遍历行为. 缺省情况下用deq ...

最新文章

  1. 我要是长得和姚明一样高,是不是也能打进NBA?
  2. tfjob的一篇文章,跟公司内使用方式类似
  3. 使用行为树(Behavior Tree)实现网游奖励掉落系统
  4. oracle截取字符串
  5. 匿名内部类使用的场景之一
  6. 白盒测试——简单分支函数测试
  7. c语言 strcpy原型,浅谈C语言中strcpy,strcmp,strlen,strcat函数原型
  8. java菜鸟到cto 图_从菜鸟到入门,掌握 Log4j
  9. 【 ORA-27102: out of memory处理】
  10. redisLock redis分布式锁
  11. java day24【Stream流、方法引用】
  12. 串口转WIFI模块通信
  13. ABBYY FineReader15最新免费下载安装地址激活2020注册机教程
  14. 扬帆际海:shopee跨境电商客服回复流程
  15. 服务器上设置密码策略不能修改,Window Server 2008 R2 在Active Directory域中不能更改服务器密码策略...
  16. Java获得随机汉字
  17. BitmapFactory压缩图片
  18. [W ParallelNative.cpp:212] Warning: Cannot set number of intraop threads after parallel work h
  19. 老股民箱底翻出发黄纸质股票 如今价值超过20万
  20. 个人开发者越来越难之-----上传应用市场的软著虐我遍体鳞伤

热门文章

  1. linux没有nmtui这个命令,linux进阶之nmtui和nmcli配置网络
  2. Django(路由配置)
  3. 求垂足坐标(计算几何)
  4. 百度竞价这几个关键词,足以月入上万!
  5. rdkit Chem 和AllChem的区别
  6. kettle日志监控
  7. 股市投资必修课十四---厘清我们的隐形决策链
  8. 【NLP】第3章 微调 BERT 模型
  9. 混沌数学之Feigenbaum模型
  10. 计算机硬件结构中负责识别,2011年计算机一级MSoffice试题及答案解析(33)