diff options
Diffstat (limited to 'db2/log/log_register.c')
-rw-r--r-- | db2/log/log_register.c | 76 |
1 files changed, 44 insertions, 32 deletions
diff --git a/db2/log/log_register.c b/db2/log/log_register.c index a6fc4c1b3b..22264e3291 100644 --- a/db2/log/log_register.c +++ b/db2/log/log_register.c @@ -7,7 +7,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)log_register.c 10.18 (Sleepycat) 5/3/98"; +static const char sccsid[] = "@(#)log_register.c 10.22 (Sleepycat) 9/27/98"; #endif /* not lint */ #ifndef NO_SYSTEM_INCLUDES @@ -36,17 +36,18 @@ log_register(dblp, dbp, name, type, idp) { DBT fid_dbt, r_name; DB_LSN r_unused; - FNAME *fnp; + FNAME *fnp, *reuse_fnp; size_t len; - u_int32_t fid; + u_int32_t maxid; int inserted, ret; char *fullname; void *namep; - fid = 0; inserted = 0; fullname = NULL; - fnp = namep = NULL; + fnp = namep = reuse_fnp = NULL; + + LOG_PANIC_CHECK(dblp); /* Check the arguments. */ if (type != DB_BTREE && type != DB_HASH && type != DB_RECNO) { @@ -63,26 +64,37 @@ log_register(dblp, dbp, name, type, idp) /* * See if we've already got this file in the log, finding the - * next-to-lowest file id currently in use as we do it. + * (maximum+1) in-use file id and some available file id (if we + * find an available fid, we'll use it, else we'll have to allocate + * one after the maximum that we found). */ - for (fid = 1, fnp = SH_TAILQ_FIRST(&dblp->lp->fq, __fname); + for (maxid = 0, fnp = SH_TAILQ_FIRST(&dblp->lp->fq, __fname); fnp != NULL; fnp = SH_TAILQ_NEXT(fnp, q, __fname)) { - if (fid <= fnp->id) - fid = fnp->id + 1; - if (!memcmp(dbp->lock.fileid, fnp->ufid, DB_FILE_ID_LEN)) { + if (fnp->ref == 0) { /* Entry is not in use. */ + if (reuse_fnp == NULL) + reuse_fnp = fnp; + continue; + } + if (!memcmp(dbp->fileid, fnp->ufid, DB_FILE_ID_LEN)) { ++fnp->ref; - fid = fnp->id; goto found; } + if (maxid <= fnp->id) + maxid = fnp->id + 1; } - /* Allocate a new file name structure. */ - if ((ret = __db_shalloc(dblp->addr, sizeof(FNAME), 0, &fnp)) != 0) + /* Fill in fnp structure. */ + + if (reuse_fnp != NULL) /* Reuse existing one. */ + fnp = reuse_fnp; + else if ((ret = __db_shalloc(dblp->addr, sizeof(FNAME), 0, &fnp)) != 0) goto err; + else /* Allocate a new one. */ + fnp->id = maxid; + fnp->ref = 1; - fnp->id = fid; fnp->s_type = type; - memcpy(fnp->ufid, dbp->lock.fileid, DB_FILE_ID_LEN); + memcpy(fnp->ufid, dbp->fileid, DB_FILE_ID_LEN); len = strlen(name) + 1; if ((ret = __db_shalloc(dblp->addr, len, 0, &namep)) != 0) @@ -90,20 +102,22 @@ log_register(dblp, dbp, name, type, idp) fnp->name_off = R_OFFSET(dblp, namep); memcpy(namep, name, len); - SH_TAILQ_INSERT_HEAD(&dblp->lp->fq, fnp, q, __fname); + /* Only do the insert if we allocated a new fnp. */ + if (reuse_fnp == NULL) + SH_TAILQ_INSERT_HEAD(&dblp->lp->fq, fnp, q, __fname); inserted = 1; found: /* Log the registry. */ - if (!F_ISSET(dblp, DB_AM_RECOVER)) { + if (!F_ISSET(dblp, DBC_RECOVER)) { r_name.data = (void *)name; /* XXX: Yuck! */ r_name.size = strlen(name) + 1; memset(&fid_dbt, 0, sizeof(fid_dbt)); - fid_dbt.data = dbp->lock.fileid; + fid_dbt.data = dbp->fileid; fid_dbt.size = DB_FILE_ID_LEN; if ((ret = __log_register_log(dblp, NULL, &r_unused, - 0, LOG_OPEN, &r_name, &fid_dbt, fid, type)) != 0) + 0, LOG_OPEN, &r_name, &fid_dbt, fnp->id, type)) != 0) goto err; - if ((ret = __log_add_logid(dblp, dbp, fid)) != 0) + if ((ret = __log_add_logid(dblp, dbp, fnp->id)) != 0) goto err; } @@ -120,13 +134,13 @@ err: /* __db_shalloc_free(dblp->addr, fnp); } + if (idp != NULL) + *idp = fnp->id; UNLOCK_LOGREGION(dblp); if (fullname != NULL) - FREES(fullname); + __os_freestr(fullname); - if (idp != NULL) - *idp = fid; return (ret); } @@ -144,6 +158,8 @@ log_unregister(dblp, fid) FNAME *fnp; int ret; + LOG_PANIC_CHECK(dblp); + ret = 0; LOCK_LOGREGION(dblp); @@ -159,7 +175,7 @@ log_unregister(dblp, fid) } /* Unlog the registry. */ - if (!F_ISSET(dblp, DB_AM_RECOVER)) { + if (!F_ISSET(dblp, DBC_RECOVER)) { memset(&r_name, 0, sizeof(r_name)); r_name.data = R_ADDR(dblp, fnp->name_off); r_name.size = strlen(r_name.data) + 1; @@ -173,22 +189,18 @@ log_unregister(dblp, fid) /* * If more than 1 reference, just decrement the reference and return. - * Otherwise, free the unique file information, name and structure. + * Otherwise, free the name. */ - if (fnp->ref > 1) - --fnp->ref; - else { + --fnp->ref; + if (fnp->ref == 0) __db_shalloc_free(dblp->addr, R_ADDR(dblp, fnp->name_off)); - SH_TAILQ_REMOVE(&dblp->lp->fq, fnp, q, __fname); - __db_shalloc_free(dblp->addr, fnp); - } /* * Remove from the process local table. If this operation is taking * place during recovery, then the logid was never added to the table, * so do not remove it. */ - if (!F_ISSET(dblp, DB_AM_RECOVER)) + if (!F_ISSET(dblp, DBC_RECOVER)) __log_rem_logid(dblp, fid); ret1: UNLOCK_LOGREGION(dblp); |