📄 tcl_mp.c
字号:
"close", "fsync", "get", NULL }; enum mpcmds { MPCLOSE, MPFSYNC, MPGET }; DB_MPOOLFILE *mp; int cmdindex, length, result, ret; DBTCL_INFO *mpip; Tcl_Obj *res; char *obj_name; Tcl_ResetResult(interp); mp = (DB_MPOOLFILE *)clientData; obj_name = Tcl_GetStringFromObj(objv[0], &length); mpip = _NameToInfo(obj_name); result = TCL_OK; if (mp == NULL) { Tcl_SetResult(interp, "NULL mp pointer", TCL_STATIC); return (TCL_ERROR); } if (mpip == NULL) { Tcl_SetResult(interp, "NULL mp info pointer", TCL_STATIC); return (TCL_ERROR); } /* * Get the command name index from the object based on the dbcmds * defined above. */ if (Tcl_GetIndexFromObj(interp, objv[1], mpcmds, "command", TCL_EXACT, &cmdindex) != TCL_OK) return (IS_HELP(objv[1])); res = NULL; switch ((enum mpcmds)cmdindex) { case MPCLOSE: if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, NULL); return (TCL_ERROR); } _debug_check(); ret = mp->close(mp, 0); result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "mp close"); _MpInfoDelete(interp, mpip); (void)Tcl_DeleteCommand(interp, mpip->i_name); _DeleteInfo(mpip); break; case MPFSYNC: if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, NULL); return (TCL_ERROR); } _debug_check(); ret = mp->sync(mp); res = Tcl_NewIntObj(ret); break; case MPGET: result = tcl_MpGet(interp, objc, objv, mp, mpip); break; } /* * Only set result if we have a res. Otherwise, lower * functions have already done so. */ if (result == TCL_OK && res) Tcl_SetObjResult(interp, res); return (result);}/* * tcl_MpGet -- */static inttcl_MpGet(interp, objc, objv, mp, mpip) Tcl_Interp *interp; /* Interpreter */ int objc; /* How many arguments? */ Tcl_Obj *CONST objv[]; /* The argument objects */ DB_MPOOLFILE *mp; /* mp pointer */ DBTCL_INFO *mpip; /* mp info pointer */{ static char *mpget[] = { "-create", "-last", "-new", NULL }; enum mpget { MPGET_CREATE, MPGET_LAST, MPGET_NEW }; DBTCL_INFO *ip; Tcl_Obj *res; db_pgno_t pgno; u_int32_t flag; int i, ipgno, optindex, result, ret; char newname[MSG_SIZE]; void *page; result = TCL_OK; memset(newname, 0, MSG_SIZE); i = 2; flag = 0; while (i < objc) { if (Tcl_GetIndexFromObj(interp, objv[i], mpget, "option", TCL_EXACT, &optindex) != TCL_OK) { /* * Reset the result so we don't get an errant * error message if there is another error. * This arg is the page number. */ if (IS_HELP(objv[i]) == TCL_OK) return (TCL_OK); Tcl_ResetResult(interp); break; } i++; switch ((enum mpget)optindex) { case MPGET_CREATE: flag |= DB_MPOOL_CREATE; break; case MPGET_LAST: flag |= DB_MPOOL_LAST; break; case MPGET_NEW: flag |= DB_MPOOL_NEW; break; } if (result != TCL_OK) goto error; } /* * Any left over arg is a page number. It better be the last arg. */ ipgno = 0; if (i != objc) { if (i != objc - 1) { Tcl_WrongNumArgs(interp, 2, objv, "?args? ?pgno?"); result = TCL_ERROR; goto error; } result = Tcl_GetIntFromObj(interp, objv[i++], &ipgno); if (result != TCL_OK) goto error; } snprintf(newname, sizeof(newname), "%s.pg%d", mpip->i_name, mpip->i_mppgid); ip = _NewInfo(interp, NULL, newname, I_PG); if (ip == NULL) { Tcl_SetResult(interp, "Could not set up info", TCL_STATIC); return (TCL_ERROR); } _debug_check(); pgno = ipgno; ret = mp->get(mp, &pgno, flag, &page); result = _ReturnSetup(interp, ret, DB_RETOK_MPGET(ret), "mpool get"); if (result == TCL_ERROR) _DeleteInfo(ip); else { /* * Success. Set up return. Set up new info * and command widget for this mpool. */ mpip->i_mppgid++; ip->i_parent = mpip; ip->i_pgno = pgno; ip->i_pgsz = mpip->i_pgsz; _SetInfoData(ip, page); Tcl_CreateObjCommand(interp, newname, (Tcl_ObjCmdProc *)pg_Cmd, (ClientData)page, NULL); res = Tcl_NewStringObj(newname, strlen(newname)); Tcl_SetObjResult(interp, res); }error: return (result);}/* * pg_Cmd -- * Implements the "pg" widget. */static intpg_Cmd(clientData, interp, objc, objv) ClientData clientData; /* Page handle */ Tcl_Interp *interp; /* Interpreter */ int objc; /* How many arguments? */ Tcl_Obj *CONST objv[]; /* The argument objects */{ static char *pgcmds[] = { "init", "is_setto", "pgnum", "pgsize", "put", "set", NULL }; enum pgcmds { PGINIT, PGISSET, PGNUM, PGSIZE, PGPUT, PGSET }; DB_MPOOLFILE *mp; int cmdindex, length, result; char *obj_name; void *page; DBTCL_INFO *pgip; Tcl_Obj *res; Tcl_ResetResult(interp); page = (void *)clientData; obj_name = Tcl_GetStringFromObj(objv[0], &length); pgip = _NameToInfo(obj_name); mp = NAME_TO_MP(pgip->i_parent->i_name); result = TCL_OK; if (page == NULL) { Tcl_SetResult(interp, "NULL page pointer", TCL_STATIC); return (TCL_ERROR); } if (mp == NULL) { Tcl_SetResult(interp, "NULL mp pointer", TCL_STATIC); return (TCL_ERROR); } if (pgip == NULL) { Tcl_SetResult(interp, "NULL page info pointer", TCL_STATIC); return (TCL_ERROR); } /* * Get the command name index from the object based on the dbcmds * defined above. */ if (Tcl_GetIndexFromObj(interp, objv[1], pgcmds, "command", TCL_EXACT, &cmdindex) != TCL_OK) return (IS_HELP(objv[1])); res = NULL; switch ((enum pgcmds)cmdindex) { case PGNUM: res = Tcl_NewLongObj((long)pgip->i_pgno); break; case PGSIZE: res = Tcl_NewLongObj(pgip->i_pgsz); break; case PGSET: case PGPUT: result = tcl_Pg(interp, objc, objv, page, mp, pgip, cmdindex == PGSET ? 0 : 1); break; case PGINIT: result = tcl_PgInit(interp, objc, objv, page, pgip); break; case PGISSET: result = tcl_PgIsset(interp, objc, objv, page, pgip); break; } /* * Only set result if we have a res. Otherwise, lower * functions have already done so. */ if (result == TCL_OK && res) Tcl_SetObjResult(interp, res); return (result);}static inttcl_Pg(interp, objc, objv, page, mp, pgip, putop) Tcl_Interp *interp; /* Interpreter */ int objc; /* How many arguments? */ Tcl_Obj *CONST objv[]; /* The argument objects */ void *page; /* Page pointer */ DB_MPOOLFILE *mp; /* Mpool pointer */ DBTCL_INFO *pgip; /* Info pointer */ int putop; /* Operation */{ static char *pgopt[] = { "-clean", "-dirty", "-discard", NULL }; enum pgopt { PGCLEAN, PGDIRTY, PGDISCARD }; u_int32_t flag; int i, optindex, result, ret; result = TCL_OK; i = 2; flag = 0; while (i < objc) { if (Tcl_GetIndexFromObj(interp, objv[i], pgopt, "option", TCL_EXACT, &optindex) != TCL_OK) return (IS_HELP(objv[i])); i++; switch ((enum pgopt)optindex) { case PGCLEAN: flag |= DB_MPOOL_CLEAN; break; case PGDIRTY: flag |= DB_MPOOL_DIRTY; break; case PGDISCARD: flag |= DB_MPOOL_DISCARD; break; } } _debug_check(); if (putop) ret = mp->put(mp, page, flag); else ret = mp->set(mp, page, flag); result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "page"); if (putop) { (void)Tcl_DeleteCommand(interp, pgip->i_name); _DeleteInfo(pgip); } return (result);}static inttcl_PgInit(interp, objc, objv, page, pgip) Tcl_Interp *interp; /* Interpreter */ int objc; /* How many arguments? */ Tcl_Obj *CONST objv[]; /* The argument objects */ void *page; /* Page pointer */ DBTCL_INFO *pgip; /* Info pointer */{ Tcl_Obj *res; size_t pgsz; long *p, *endp, newval; int length, result; u_char *s; result = TCL_OK; if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "val"); return (TCL_ERROR); } pgsz = pgip->i_pgsz; result = Tcl_GetLongFromObj(interp, objv[2], &newval); if (result != TCL_OK) { s = Tcl_GetByteArrayFromObj(objv[2], &length); if (s == NULL) return (TCL_ERROR); memcpy(page, s, ((size_t)length < pgsz) ? (size_t)length : pgsz); result = TCL_OK; } else { p = (long *)page; for (endp = p + (pgsz / sizeof(long)); p < endp; p++) *p = newval; } res = Tcl_NewIntObj(0); Tcl_SetObjResult(interp, res); return (result);}static inttcl_PgIsset(interp, objc, objv, page, pgip) Tcl_Interp *interp; /* Interpreter */ int objc; /* How many arguments? */ Tcl_Obj *CONST objv[]; /* The argument objects */ void *page; /* Page pointer */ DBTCL_INFO *pgip; /* Info pointer */{ Tcl_Obj *res; size_t pgsz; long *p, *endp, newval; int length, result; u_char *s; result = TCL_OK; if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "val"); return (TCL_ERROR); } pgsz = pgip->i_pgsz; result = Tcl_GetLongFromObj(interp, objv[2], &newval); if (result != TCL_OK) { if ((s = Tcl_GetByteArrayFromObj(objv[2], &length)) == NULL) return (TCL_ERROR); result = TCL_OK; if (memcmp(page, s, ((size_t)length < pgsz) ? (size_t)length : pgsz ) != 0) { res = Tcl_NewIntObj(0); Tcl_SetObjResult(interp, res); return (result); } } else { p = (long *)page; /* * If any value is not the same, return 0 (is not set to * this value). Otherwise, if we finish the loop, we return 1 * (is set to this value). */ for (endp = p + (pgsz/sizeof(long)); p < endp; p++) if (*p != newval) { res = Tcl_NewIntObj(0); Tcl_SetObjResult(interp, res); return (result); } } res = Tcl_NewIntObj(1); Tcl_SetObjResult(interp, res); return (result);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -