联系我们
    插件电感_大电流电感
热门搜索
点击排行
推荐电感
推荐阅读
推荐电感
推荐电感
猜猜你喜欢的
行业知识 您所在的位置: 电感 > 行业知识

SQLite系统构架及虚拟机分析

来源:    作者:    发布时间:2015-08-20 07:50:49    浏览量:

struct Vdbe {
sqlite3 *db; /* 数据库连接 */
Op *aOp; /* 保存虚拟机的空间 */
… /* 其他指令 */
int nOp; /* 生成的指令的条数 */
char *zSql; /* SQL语句 */
… /* 其他指令 */
SubProgram *pProgram; /* 虚拟机使用的其他子程序,
链表 */
};
一个虚拟机实例可以有多个子程序,每个子程序可以由多条指令组成。下面是子程序的结构:
struct SubProgram {
VdbeOp *aOp; /* 指令 */
int nOp; /* 指令条数 */
int nMem; /* 需要的内部空间 */
int nCsr; /* 需要的游标 */
void *token; /* 循环触发时需要的id */
SubProgram *pNext; /* 链表的下一个 */


};
现在的SQLite有142条操作指令,都定义在opcodes.h中,在vdbe.c中有相应的源代码,将解析一些指令作为代表,详细的技术文档可以查看官方文档。所有的指令大概可以分为3类:
(1)数据操作:包含算术、逻辑运算、字符串操作等;
(2)数据管理:主要关于内存和磁盘的操作。内存上如栈(stack)操作、数据的传送等,磁盘操作主要是B-Tree和Pager模块,包括打开及操作游标、事务的开始与结束等;
(3)控制流:指令的跳转。
SQL语句在生成VDBE程序后,每条指令包含了一个操作码(opcode)和至多5个操作数(operands:P1、P2、P3、P4和P5)。其中:
(1)P1、P2、P3都是32 bit的带符号整数,它们通常引用的是寄存器。
(2)P2在所有的有跳转功能的指令中表示目的地址。例如上面的第2条指令将会跳转到第10条指令,然后顺序执行。
(3)P4可以是32 bit或者64 bit的带符号整型数据、字符串、BLOB数据(二进制大对象)、函数指针等其他多样的对象。
(4)P5通常是无符号的字符,充当的是标识位。
在SQLite的VDBE内部,所有的指令都是VdbeOp结构的一个实例(定义在vdbe.h中),结构的定义也主要是这5个操作数。
struct VdbeOp {
u8 opcode; /* 操作码类型 */
… /* 其他数据接口 */
signed char p4type; /* p4 的类型 */
u8 p5; /* p5是无符号字符型 */
int p1; /* 操作数1 */
int p2; /* 操作数2,通常是跳转指令的目的 */
int p3; /* 操作数3 */
union { /* ... */ } p4; /* p4 是一个联合,
可以有不同的类型 */
… /* 其他数据接口 */
};
由代码生成器生成的程序交由VM执行。sqlite3_step()会触发内部vdbe解释生成的vdbe指令。指令的执行在如下的函数中进行(SQLITE_PRIVATE 即为static关键字),此处去掉了烦琐的细节,只展示其中的关键结构和一个指令的执行。
SQLITE_PRIVATE int sqlite3VdbeExec(
Vdbe *p /* VDBE 实例 */
) {
int pc; /* 程序计数器 */
Op *aOp = p->aOp; /* 得到所有的指令 */
Op *pOp; /* 当前指令 */
int rc= SQLITE_OK; /* 返回值 */
sqlite3* db = p->db; /* 数据库连接实例 */
u8 encoding = ENC(db);/* UTF-8编码 */
… /* 其他初始化代码 */
switch ( pOp->opcode ) { /* 在此之后就是一个
非常大的case代码
case OP_Goto: {
CHECK_FOR_INTERRUPT;
pc=pOp->p2-1;/* 调整程序计数器 */
break;
}
… /* 其他的case指令 */
}
… /* 其他指令 */
}
这个函数是整个VDBE的核心执行函数,虽然重要,但是代码的原理非常简单,就是一系列的switch-case语句。在相应的case情况下,会执行相应的底层代码,进行数据库的磁盘操作。
3 实验
3.1 数据库编程接口
SQLite的编程模型比较简单,下面的例子给出了一个基本的框架。
#include "sqlite3.h"
#include <stdlib.h>
int main(int argc, char **argv)
{
char *file = "./test.db";/* 数据库文件 */
sqlite3 *db = NULL; /* 数据库连接实例 */
int rc = 0; /* 返回值 */
sqlite3_initialize(); /* 初始库 */
rc= sqlite3_open_v2(file, &db,
SQLITE_OPEN_READWRITE, NULL);
/* 准备SQL语句,生成VDBE程序 */
sqlite3_stmt *stmt = NULL:
rc=sqlite3_prepare_v2(db, "SELECT * FROM FILM",
-1, &stmt, NULL);
if (rc != SQLITE_OK) exit(-1);
while (sqlite3_step(stmt) == SQLITE_ROW) {
const char *data = (const char*)
sqlite3_column_text(stmt, 0);
printf("%s\n", data?data:"[NULL]");
}
sqlite3_finalize(stmt);
sqlite3_close(db); /* 关闭 */
sqlite3_shutdown(); /* 释放资源 */
}
在上面的例子中,使用了sqlite3_prepare_v2()和sqlite3_

新手求教protel99se在画PCB时铜皮导线是直接用画线工具然后设置合适的线宽来画,还是用画线工具划出不规则线路(多边形)然后填充成一条线路?根据自己选择适合的,什么事情不可能是一次性就能画得好的,

嵌入式软件与硬件的集成测试过程研究 引言软件质量即业务生命。软件测试项目已经变得比以往任何时候都复杂和困难。1979年,Glenford Myers在《The Art of Software Testing》一书中提出 测试的目的是证

开关电源技术发展历程的十个关注点 4月08日 第三届·无线通信技术研讨会 立即报名 12月04日 2015•第二届中国IoT大会 精彩回顾 10月30日ETF•智能硬件开发技术培训会 精彩回顾 10月23日ETF•第三届 消费

大电流电感
 
在线客服