/* * the idea id to print each context description at most once but provide enough * info for deducing the current execution stack */ static void ctx_print(void) { /* lock so _db_print will not call us recursively */ Ctx_Lock++; /* ok, user saw [0,Ctx_Reported_Level] descriptions */ /* first inform about entries popped since user saw them */ if (Ctx_Valid_Level < Ctx_Reported_Level) { if (Ctx_Reported_Level != Ctx_Valid_Level + 1) _db_print("ctx: exit levels from %2d down to %2d\n", Ctx_Reported_Level, Ctx_Valid_Level + 1); else _db_print("ctx: exit level %2d\n", Ctx_Reported_Level); Ctx_Reported_Level = Ctx_Valid_Level; } /* report new contexts that were pushed since last report */ while (Ctx_Reported_Level < Ctx_Current_Level) { Ctx_Reported_Level++; Ctx_Valid_Level++; _db_print("ctx: enter level %2d: '%s'\n", Ctx_Reported_Level, ctx_get_descr(Ctx_Reported_Level)); } /* unlock */ Ctx_Lock--; }
/********************************* 新增虚拟文件 入参: dbHandle 库句柄 出参: pVfile 虚文件控制结构指针。 返回值: _DB_SUCCESS 新增成功。 _DB_E_MEM_NO_PAGE 内存池页面不够,虚文件创建失败。 _DB_ERROR 其他错误,创建失败。 ************************************/ _DB_RET _db_vfile_create(_db_t_database_handle dbHandle, _db_t_vfile *pVfile) { _db_t_mem_head *pMemHead; DWORD rootPage; DWORD pageNo; VOID *pAddr; _DB_RET ret; /* 初始化文件控制结构 */ pVfile->dirLevel = 0; pVfile->rootPage = _DB_PAGE_INVALID; pVfile->pageNum = 0; pVfile->fileSize = 0; pVfile->currentOffset = 0; pMemHead = (_db_t_mem_head *)_DB_GET_MEM_HEAD(dbHandle); /* 生成一级目录页面 */ ret = _db_mem_page_new(dbHandle, &rootPage); if (ret != _DB_SUCCESS) { _db_print(LOG_ERROR, "File %s, line %d: vfile create error!\n", __FILE__, __LINE__); return ret; } pAddr = _db_mem_get_page_addr(dbHandle, rootPage); if (NULL == pAddr) { _db_print(LOG_ERROR, "File %s, line %d: vfile create error!\n", __FILE__, __LINE__); _db_mem_page_release(dbHandle, rootPage); return _DB_ERROR; } memset(pAddr, 0xff, pMemHead->pageSize); /* 为文件添加第一个页面 */ ret = _db_mem_page_new(dbHandle, &pageNo); if (ret != _DB_SUCCESS) { _db_mem_page_release(dbHandle, rootPage); return ret; } *(DWORD *)pAddr = pageNo; pVfile->rootPage = rootPage; pVfile->pageNum = 1; pVfile->dirLevel = 1; return _DB_SUCCESS; }
/********************************* 文件分配表扩容,增加一层 入参: dbHandle 库句柄。 pVfile 虚文件控制结构 出参: 返回值: _DB_SUCCESS 扩容成功 其它 扩容失败 说明: ************************************/ static _DB_RET _db_vfile_add_level(_db_t_database_handle dbHandle, _db_t_vfile *pVfile) { _db_t_mem_head *pMemHead; VOID *pAddr; DWORD pageNo; _DB_RET ret; pMemHead = (_db_t_mem_head *)_DB_GET_MEM_HEAD(dbHandle); if (pVfile->dirLevel >= _DB_VFILE_MAX_LEVEL) { _db_print(LOG_ERROR, "File %s, line %d: vfile dir level overflow!\n", __FILE__, __LINE__); return _DB_ERROR; } /* 增加新的根目录页面 */ ret = _db_mem_page_new(dbHandle, &pageNo); if (ret != _DB_SUCCESS) { _db_print(LOG_ERROR, "File %s, line %d: vfile create page error!\n", __FILE__, __LINE__); return ret; } pAddr = _db_mem_get_page_addr(dbHandle, pageNo); if (NULL == pAddr) { _db_print(LOG_ERROR, "File %s, line %d: vfile get page addr error!\n", __FILE__, __LINE__); _db_mem_page_release(dbHandle, pageNo); return _DB_ERROR; } memset(pAddr, 0xff, pMemHead->pageSize); /* 目录链接 */ *(DWORD *)pAddr = pVfile->rootPage; pVfile->rootPage = pageNo; pVfile->dirLevel++; return _DB_SUCCESS; }
// the callback in the server called by a communication backend // on each comm. protocol command void handler (ULONG obj, int ncmd, int data, int threadNum) { int rc, l, len; char buf[256]; switch(ncmd) { case F_CMD_GET_IHAB: { int iHAB = 1, inf[2]; static int iClientId = 1; debug(0, 2)("Fs_ClientWork: F_CMD_GET_IHAB not yet full implemented\n"); iClientId++; iHAB = session.hab_list.Add(iClientId ,threadNum); inf[0] = iHAB; inf[1] = iClientId; rc= F_SendDataToClient(obj, inf , sizeof(inf)); } break; case F_CMD_CLIENT_EXIT: //todo: clear ihab = data debug(0, 2) ("Fs_ClientWork: F_CMD_CLIENT_EXIT %x ; not yet implemented\n", data); break; case F_CMD_WINPOSTMSG: { SQMSG sqmsg; int rc1,ihabto; rc = F_RecvDataFromClient(obj, &sqmsg, &l, sizeof(SQMSG)); debug(0, 2) ("Fs_ClientWork: F_CMD_WINPOSTMSG get %i bytes\n",l); if(rc == 0 && l == sizeof(SQMSG)) { rc1 = _WndList.QueryHab(sqmsg.qmsg.hwnd, ihabto); if(rc1 == 1) { sqmsg.ihto = ihabto; rc = session.hab_list.Queue.Add(&sqmsg); } } } break; case F_CMD_WINSENDMSG: { SQMSG sqmsg; int rc1,ihabto; rc = F_RecvDataFromClient(obj, &sqmsg, &l, sizeof(SQMSG)); debug(0, 2) ("Fs_ClientWork: F_CMD_WINPOSTMSG get %i bytes\n",l); if(rc == 0 && l == sizeof(SQMSG)) { rc1 = _WndList.QueryHab(sqmsg.qmsg.hwnd, ihabto); if(rc1 == 1) { sqmsg.ihto = ihabto; //todo: it is sendmsg == postmsg implementation //it seems that we must wait in client via call to CMD_WINQUERYPOSTED or smth like it rc = session.hab_list.Queue.Add(&sqmsg); } } } break; case F_CMD_WINQUERY_MSG: /* Query messages for ihab = data */ { int nmsg=0; int ihabto; ihabto = data; nmsg = session.hab_list.Queue.QueryNmsg(ihabto); if (nmsg) debug(0, 2) ("Fs_ClientWork: F_CMD_WINQUERY_MSG, nmsg=%i\n",nmsg); rc = F_SendDataToClient(obj, &nmsg , sizeof(int)); } break; case F_CMD_WINGET_MSG: /* Get message for ihab = data */ { SQMSG sqmsg; int rc, ihabto; int nmsg=0; ihabto = data; rc = session.hab_list.Queue.GetForIhab(&sqmsg, ihabto); if (rc == 0) nmsg = 1; if (nmsg == 1) debug(0, 2) ("Fs_ClientWork: F_CMD_WINGET_MSG for %i, msg=%x\n", ihabto, sqmsg.qmsg.msg); else debug(0, 2) ("Fs_ClientWork: F_CMD_WINGET_MSG, No msg for %i\n", ihabto); rc = F_SendDataToClient(obj, &nmsg , sizeof(int)); if(nmsg) rc = F_SendDataToClient(obj, &sqmsg.qmsg , sizeof(QMSG)); } break; case F_CMD_WINCREATE_HWND: { HWND hwnd; int iHab; iHab = data; hwnd = _WndList.Add(iHab); //todo: set _WndList with thread info and cleanup at thread(client exit) end rc= F_SendDataToClient(obj, &hwnd , sizeof(HWND)); } break; case F_CMD_WINSET_PARENT_HWND: { HWND hwnd, hwndParent; hwnd = data; rc = F_RecvDataFromClient(obj, (void *)&hwndParent, &len, sizeof(HWND)); rc = _WndList.SetParent(hwnd, hwndParent); } break; case F_CMD_GET_HPS: { HWND hwnd; HPS hps; hwnd = data; hps = _WndList.GetHPS(hwnd); rc= F_SendDataToClient(obj, &hps, sizeof(HPS)); } break; case F_CMD_RELEASE_HPS: { HPS hps; int rc1; hps = data; rc1 = _WndList.ReleaseHPS(hps); rc= F_SendDataToClient(obj, &rc1, sizeof(int)); } break; case F_CMD_WIN_SET_WND_SIZE: { HWND hwnd = data; int par[2],rc1; rc = F_RecvDataFromClient(obj, (void *)&par[0], &len, sizeof(int)*2); rc1 = 0; //todo rc= F_SendDataToClient(obj, &rc1, sizeof(int)); } break; case F_CMD_WIN_SET_WND_POS: { HWND hwnd = data; int par[2],rc1; rc = F_RecvDataFromClient(obj, (void *)&par[0], &len, sizeof(int)*2); rc1 = 0; //todo rc= F_SendDataToClient(obj, &rc1, sizeof(int)); } break; case F_CMD_WIN_GET_WND_SWP: { HWND hwnd = data; SWP swp; //todo rc= F_SendDataToClient(obj, &swp, sizeof(SWP)); } break; case F_CMD_WIN_SHOW: { HWND hwnd = data; int par,rc1; rc = F_RecvDataFromClient(obj, (void *)&par, &len, sizeof(int)); rc1 = 0; //todo rc= F_SendDataToClient(obj, &rc1, sizeof(int)); } break; case F_CMD_GPI_SET_COLOR: { HPS hps; int color, len, rc1=FALSE; hps = data; rc = F_RecvDataFromClient(obj, (void *)&color, &len, sizeof(int)); debug(0, 0) ("F_CMD_GPI_SET_COLOR: get hps=%x, color=%x, len=%i\n",hps,color,len); if(hps >= 0 && hps < _WndList.numPS) { if(_WndList.pPS[hps].used) /* rc1 = F_GpiSetColor(&_WndList.pPS[hps], color); */ rc1 = F_PS_GpiSetColor(&_WndList.pPS[hps], color); } rc= F_SendDataToClient(obj, &rc1, sizeof(int)); } break; case F_CMD_GPI_MOVE: { HPS hps; int rc1=FALSE; POINTL Point; hps = data; rc = F_RecvDataFromClient(obj, (void *)&Point, &len, sizeof(POINTL)); debug(0, 0) ("F_CMD_GPI_MOVE: get hps=%x,len=%i\n",hps,len); if(hps >= 0 && hps < _WndList.numPS) { if(_WndList.pPS[hps].used) rc1 = F_PS_GpiMove(&_WndList.pPS[hps], &Point); } rc= F_SendDataToClient(obj, &rc1, sizeof(int)); } break; case F_CMD_GPI_LINE: { HPS hps; int rc1=FALSE; POINTL Point; hps = data; rc = F_RecvDataFromClient(obj, (void *)&Point, &len, sizeof(POINTL)); if(hps >= 0 && hps < _WndList.numPS) { if(_WndList.pPS[hps].used) rc1 = F_PS_GpiLine(&_WndList.pPS[hps], &Point); } rc= F_SendDataToClient(obj, &rc1, sizeof(int)); } break; case F_CMD_GPI_DRAW_LINE: //TODO break; case F_CMD_GPI_DRAW_RECT: //TODO break; case F_CMD_DB_PRINT: { F_RecvDataFromClient(obj, (char *)buf, &len, sizeof(buf)); _db_print(buf); } break; case F_CMD_FATAL_COMMON: F_RecvDataFromClient(obj, (char *)buf, &len, sizeof(buf)); _fatal_common(buf); break; #define POKA 0 #if POKA case 1: debug(0, 2) ("Fs_ClientWork: Get ncmd %x %x\n", ncmd, data); rc=F_SendCmdToServer(obj, ncmd, data); switch(data) { case S_SHUTDOWN: // squid_signal(SIGTERM, shut_down, SA_NODEFER | SA_RESETHAND | SA_RESTART); // debug(0, 0) ("squid_signal:\n"); DosSleep(100); rc = raise(SIGTERM); // debug(0, 0) ("raise: rc =%x %s\n",rc,xstdio_strerror()); break; case S_RECONFIGURE: // do_reconfigure = 1; break; case S_ROTATE: // do_rotate = 1; break; case S_DEBUG: break; case S_KILL: debug(1, 1) ("Preparing for killing\n"); // do_shutdown++; // SquidShutdown(NULL); break; } ncmd = 0; break; #endif //POKA default: debug(0, 2) ("Fs_ClientWork:WARNING: Unimplemented cmd %x\n", ncmd); ncmd = 0; break; } //endof switch(ncmd) }
/********************************** 自当前偏移处,读虚拟文件。 入参: dbHandle 库句柄。 pVfile 虚文件控制结构指针。 dest 目的缓冲区。 len 数据长度 出参: 返回值: _DB_SUCCESS 读文件成功。 _DB_E_FILE_LEN 长度无效。 _DB_ERROR 其他读失败。 说明: 读成功,文件当前偏移 = 原偏移 + 读长度 ***********************************/ _DB_RET _db_vfile_read(_db_t_database_handle dbHandle, _db_t_vfile *pVfile, VOID *dest, DWORD len) { _db_t_mem_head *pMemHead; DWORD lgcPageNo; DWORD readed = 0; WORD pageOffset; WORD toRead; WORD pageSize; if ((0 == len) || (NULL == dest)) { _db_print(LOG_ERROR, "File %s, line %d: Wrong input! Vfile read error!\n", __FILE__, __LINE__); return _DB_E_FILE_LEN; } if (pVfile->currentOffset + len > pVfile->fileSize) { _db_print(LOG_ERROR, "File %s, line %d: Wrong input! Vfile read error!\n", __FILE__, __LINE__); return _DB_E_FILE_LEN; } pMemHead = (_db_t_mem_head *)_DB_GET_MEM_HEAD(dbHandle); pageSize = pMemHead->pageSize; /* 定位逻辑页面 */ lgcPageNo = pVfile->currentOffset >> pMemHead->pageShift; pageOffset = (WORD)(pVfile->currentOffset & pMemHead->pageMask); if (pageOffset > 0) { if (pageOffset + len <= pageSize) { /* 在文件已有页面完成数据的读 */ if (_DB_SUCCESS != _db_vfile_page_read(dbHandle, pVfile, lgcPageNo, pageOffset, dest, (WORD)len)) { _db_print(LOG_ERROR, "File %s, line %d: Vfile read error!\n", __FILE__, __LINE__); return _DB_ERROR; } pVfile->currentOffset += len; return _DB_SUCCESS; } toRead = pageSize - pageOffset; if (_DB_SUCCESS != _db_vfile_page_read(dbHandle, pVfile, lgcPageNo, pageOffset, dest, toRead)) { _db_print(LOG_ERROR, "File %s, line %d: Vfile read error!\n", __FILE__, __LINE__); return _DB_ERROR; } readed += toRead; lgcPageNo++; } while (lgcPageNo < pVfile->pageNum) { if (readed + pageSize >= len) { /* 在文件已有页面完成数据的读入 */ toRead = (WORD)(len - readed); if (_DB_SUCCESS != _db_vfile_page_read(dbHandle, pVfile, lgcPageNo, 0, (BYTE *)dest + readed, toRead)) { _db_print(LOG_ERROR, "File %s, line %d: Vfile read error!\n", __FILE__, __LINE__); return _DB_ERROR; } pVfile->currentOffset += len; return _DB_SUCCESS; } toRead = pageSize; if (_DB_SUCCESS != _db_vfile_page_read(dbHandle, pVfile, lgcPageNo, 0, (BYTE *)dest + readed, toRead)) { _db_print(LOG_ERROR, "File %s, line %d: Vfile read error!\n", __FILE__, __LINE__); return _DB_ERROR; } readed += toRead; lgcPageNo++; } _db_print(LOG_ERROR, "File %s, line %d: Vfile read error!\n", __FILE__, __LINE__); return _DB_ERROR; }
/********************************** 自当前偏移处,改写虚拟文件。 入参: dbHandle 库句柄。 pVfile 虚文件控制结构指针。 src 待写的数据内容。 len 数据长度 出参: 返回值: _DB_SUCCESS 写文件成功。 _DB_E_MEM_NO_PAGE 内存池页面不够,虚文件改写失败。 _DB_ERROR 其他错误,写失败。 说明: 改写成功,文件当前偏移 = 原偏移 + 改写长度 注意:文件的长度并非 = 页面数 * 页面大小 ***********************************/ _DB_RET _db_vfile_write(_db_t_database_handle dbHandle, _db_t_vfile *pVfile, VOID *src, DWORD len) { _db_t_mem_head *pMemHead; DWORD lgcPageNo; DWORD writed = 0; WORD pageOffset; WORD toWrite; WORD pageSize; _DB_RET ret; pMemHead = (_db_t_mem_head *)_DB_GET_MEM_HEAD(dbHandle); pageSize = pMemHead->pageSize; if ((0 == len) || (NULL == src)) { _db_print(LOG_ERROR, "File %s, line %d: Wrong input! Vfile write error!\n", __FILE__, __LINE__); return _DB_ERROR; } /* 定位逻辑页面 */ lgcPageNo = pVfile->currentOffset >> pMemHead->pageShift; pageOffset = (WORD)(pVfile->currentOffset & pMemHead->pageMask); if ((lgcPageNo < pVfile->pageNum) && (pageOffset > 0)) { if (pageOffset + len <= pageSize) { /* 在文件已有页面完成数据的写入 */ if (_DB_SUCCESS != _db_vfile_page_write(dbHandle, pVfile, lgcPageNo, pageOffset, src, (WORD)len)) { _db_print(LOG_ERROR, "File %s, line %d:Vfile write error!\n", __FILE__, __LINE__); return _DB_ERROR; } pVfile->currentOffset += len; if (pVfile->currentOffset > pVfile->fileSize) { pVfile->fileSize = pVfile->currentOffset; } return _DB_SUCCESS; } toWrite = pageSize - pageOffset; if (_DB_SUCCESS != _db_vfile_page_write(dbHandle, pVfile, lgcPageNo, pageOffset, src, toWrite)) { _db_print(LOG_ERROR, "File %s, line %d:Vfile write error!\n", __FILE__, __LINE__); return _DB_ERROR; } writed += toWrite; lgcPageNo++; } while (writed < len) { if (lgcPageNo >= pVfile->pageNum) { /* 文件页面数不够,申请新的页面 */ ret = _db_vfile_add_page(dbHandle, pVfile); if (_DB_SUCCESS != ret) { _db_print(LOG_ERROR, "File %s, line %d:Vfile add page error!\n", __FILE__, __LINE__); return ret; } } if (writed + pageSize >= len) { /* 在文件已有页面完成数据的写入 */ toWrite = (WORD)(len - writed); if (_DB_SUCCESS != _db_vfile_page_write(dbHandle, pVfile, lgcPageNo, 0, (BYTE *)src + writed, toWrite)) { _db_print(LOG_ERROR, "File %s, line %d:Vfile write error!\n", __FILE__, __LINE__); return _DB_ERROR; } pVfile->currentOffset += len; if (pVfile->currentOffset > pVfile->fileSize) { pVfile->fileSize = pVfile->currentOffset; } return _DB_SUCCESS; } toWrite = pageSize; if (_DB_SUCCESS != _db_vfile_page_write(dbHandle, pVfile, lgcPageNo, 0, (BYTE *)src + writed, toWrite)) { _db_print(LOG_ERROR, "File %s, line %d:Vfile write error!\n", __FILE__, __LINE__); return _DB_ERROR; } writed += toWrite; lgcPageNo++; } _db_print(LOG_ERROR, "File %s, line %d:Vfile write error!\n", __FILE__, __LINE__); return _DB_ERROR; }
/********************************* 删除虚拟文件 入参: dbHandle 库句柄 pVfile 虚文件控制结构指针。 出参: 返回值: _DB_SUCCESS 删除成功。 _DB_ERROR 失败。 ************************************/ _DB_RET _db_vfile_remove(_db_t_database_handle dbHandle, _db_t_vfile *pVfile) { _db_t_mem_head *pMemHead; DWORD *pAddr; DWORD deleted = 0; _db_t_vfile_node nodeStack[_DB_VFILE_MAX_LEVEL]; BYTE stackNodeNum = 0; WORD itemNumPerPage; WORD itemInPage; DWORD brother; _db_t_vfile_node curNode; pMemHead = (_db_t_mem_head *)_DB_GET_MEM_HEAD(dbHandle); itemNumPerPage = pMemHead->pageSize >> 2; if (pVfile->dirLevel > _DB_VFILE_MAX_LEVEL) { _db_print(LOG_ERROR, "File %s, line %d: vfile dir level overflow!\n", __FILE__, __LINE__); return _DB_ERROR; } /* 使用堆栈,按深度对树进行遍历 */ curNode.node = pVfile->rootPage; curNode.father = _DB_PAGE_INVALID; curNode.level = 1; /* 根节点为第一层 */ curNode.childOrder = 0; while (_DB_PAGE_INVALID != curNode.node) { if (_DB_PAGE_INVALID != curNode.father) { if (curNode.childOrder < itemNumPerPage) { pAddr = (DWORD *)_db_mem_get_page_addr(dbHandle, curNode.father); brother = *(pAddr + curNode.childOrder); if (_DB_PAGE_INVALID != brother) { /* 当前节点的右兄弟非空,将其压入堆栈 */ if (stackNodeNum >= _DB_VFILE_MAX_LEVEL) { _db_print(LOG_ERROR, "File %s, line %d: Vfile dir destroyed! Delete error!\n", __FILE__, __LINE__); return _DB_ERROR; } nodeStack[stackNodeNum].node = brother; nodeStack[stackNodeNum].father = curNode.father; nodeStack[stackNodeNum].childOrder = curNode.childOrder + 1; nodeStack[stackNodeNum].level = curNode.level; stackNodeNum++; } else { /* 最后一个孩子,释放父节点 */ _db_mem_page_release(dbHandle, curNode.father); } } else { /* 最后一个孩子,释放父节点 */ _db_mem_page_release(dbHandle, curNode.father); } } /* 对当前节点的处理 */ if (curNode.level == pVfile->dirLevel) { /* 如果是叶子节点,那么直接释放叶子目录上的数据页面,并回收该节点 */ pAddr = _db_mem_get_page_addr(dbHandle, curNode.node); if (NULL == pAddr) { return _DB_ERROR; } itemInPage = 0; while ((itemInPage < itemNumPerPage) && (_DB_PAGE_INVALID != *pAddr)) { _db_mem_page_release(dbHandle, *pAddr); deleted++; pAddr++; itemInPage++; } _db_mem_page_release(dbHandle, curNode.node); if (stackNodeNum > 0) { /* 弹栈 */ curNode = nodeStack[stackNodeNum - 1]; stackNodeNum--; } else { /* 栈空,访问路径空,删除已完成,直接退出 */ break; } } else { /* 非叶子节点,取第一个孩子为当前节点 */ pAddr = (DWORD *)_db_mem_get_page_addr(dbHandle, curNode.node); if ((NULL == pAddr) || (_DB_PAGE_INVALID == *pAddr)) { _db_print(LOG_ERROR, "File %s, line %d: Vfile dir error!\n", __FILE__, __LINE__); return _DB_ERROR; } curNode.father = curNode.node; curNode.level++; curNode.childOrder = 1; curNode.node = *pAddr; } } /* end while */ if (deleted != pVfile->pageNum) { _db_print(LOG_ERROR, "File %s, line %d: Vfile dir destroyed! Delete error!\n", __FILE__, __LINE__); return _DB_ERROR; } pVfile->dirLevel = 0; pVfile->rootPage = _DB_PAGE_INVALID; pVfile->pageNum = 0; pVfile->fileSize = 0; pVfile->currentOffset = 0; return _DB_SUCCESS; }
/********************************* 文件新增一个数据页面 入参: dbHandle 库句柄。 pVfile 虚文件控制结构。 出参: 返回值: _DB_SUCCESS 页面申请成功。 其它 新增页面失败。 说明: ************************************/ static _DB_RET _db_vfile_add_page(_db_t_database_handle dbHandle, _db_t_vfile *pVfile) { _db_t_mem_head *pMemHead; VOID *pAddr; DWORD *pPageItem; DWORD phyPageNo; DWORD lgcPageNo; DWORD pageNo; DWORD temp; WORD lgcItem[_DB_VFILE_MAX_LEVEL]; WORD i; WORD itemNumPerPage; _DB_RET ret; pMemHead = (_db_t_mem_head *)_DB_GET_MEM_HEAD(dbHandle); /* 申请数据页面 */ ret = _db_mem_page_new(dbHandle, &phyPageNo); if (ret != _DB_SUCCESS) { _db_print(LOG_ERROR, "File %s, line %d: vfile create data page error!\n", __FILE__, __LINE__); return ret; } lgcPageNo = pVfile->pageNum; itemNumPerPage = pMemHead->pageSize >> 2; /* 判断页面分配表是否满,如果满,则扩容一层 */ temp = 1; for (i = 0; i < pVfile->dirLevel; i++) { temp *= itemNumPerPage; } if (lgcPageNo >= temp) { ret = _db_vfile_add_level(dbHandle, pVfile); if (_DB_SUCCESS != ret) { _db_print(LOG_ERROR, "File %s, line %d: vfile add dir level error!\n", __FILE__, __LINE__); _db_mem_page_release(dbHandle, phyPageNo); return ret; } } temp = lgcPageNo; /* 获取逻辑页面在每一级目录内部对应的目录项 */ for (i = pVfile->dirLevel; i > 0; i--) { lgcItem[i - 1] = (WORD)(temp % itemNumPerPage); temp = temp / itemNumPerPage; } /* 访问非叶子节点,获取目录项 */ temp = pVfile->rootPage; for (i = 0; i < pVfile->dirLevel - 1; i++) { /* 获取目录所在的物理页面 */ pAddr = _db_mem_get_page_addr(dbHandle, temp); if (NULL == pAddr) { _db_print(LOG_ERROR, "File %s, line %d: vfile get dir info error!\n", __FILE__, __LINE__); _db_mem_page_release(dbHandle, phyPageNo); return ret; } pPageItem = (DWORD *)pAddr + lgcItem[i]; if (_DB_PAGE_INVALID == *pPageItem) { /* 当前目录项为空,新建 */ ret = _db_mem_page_new(dbHandle, &pageNo); if (ret != _DB_SUCCESS) { _db_print(LOG_ERROR, "File %s, line %d: vfile create dir page error!\n", __FILE__, __LINE__); _db_mem_page_release(dbHandle, phyPageNo); return ret; } pAddr = _db_mem_get_page_addr(dbHandle, pageNo); if (NULL == pAddr) { _db_print(LOG_ERROR, "File %s, line %d: get page addr error!\n", __FILE__, __LINE__); _db_mem_page_release(dbHandle, phyPageNo); _db_mem_page_release(dbHandle, pageNo); return ret; } memset(pAddr, 0xff, pMemHead->pageSize); *pPageItem = pageNo; } temp = *pPageItem; } /* 叶子节点目录页面 */ pAddr = _db_mem_get_page_addr(dbHandle, temp); pPageItem = (DWORD *)pAddr + lgcItem[i]; *pPageItem = phyPageNo; pVfile->pageNum++; return _DB_SUCCESS; }