00001
00002
00003
00004
00005
00006
00007
00008 #include "config.h"
00009
00010 #ifndef lint
00011 static const char revid[] = "$Id: db__dup_8c-source.html,v 1.1 2008/06/08 10:17:27 sebdiaz Exp $";
00012 #endif
00013
00014 #ifndef NO_SYSTEM_INCLUDES
00015 #include <sys/types.h>
00016
00017 #include <string.h>
00018 #endif
00019
00020 #include "db_int.h"
00021 #include "db_page.h"
00022 #include "db_shash.h"
00023 #include "btree.h"
00024 #include "hash.h"
00025 #include "lock.h"
00026 #include "db_am.h"
00027
00028
00029
00030
00031
00032
00033
00034 int
00035 CDB___db_ditem(dbc, pagep, indx, nbytes)
00036 DBC *dbc;
00037 PAGE *pagep;
00038 u_int32_t indx, nbytes;
00039 {
00040 DB *dbp;
00041 DBT ldbt;
00042 db_indx_t cnt, offset;
00043 int ret;
00044 u_int8_t *from;
00045
00046 dbp = dbc->dbp;
00047 if (DB_LOGGING(dbc)) {
00048 ldbt.data = P_ENTRY(pagep, indx);
00049 ldbt.size = nbytes;
00050 if ((ret = CDB___db_addrem_log(dbp->dbenv, dbc->txn,
00051 &LSN(pagep), 0, DB_REM_DUP, dbp->log_fileid, PGNO(pagep),
00052 (u_int32_t)indx, nbytes, &ldbt, NULL, &LSN(pagep))) != 0)
00053 return (ret);
00054 }
00055
00056
00057
00058
00059
00060 if (NUM_ENT(pagep) == 1) {
00061 NUM_ENT(pagep) = 0;
00062 HOFFSET(pagep) = dbp->pgsize;
00063 return (0);
00064 }
00065
00066
00067
00068
00069
00070 from = (u_int8_t *)pagep + HOFFSET(pagep);
00071 memmove(from + nbytes, from, pagep->inp[indx] - HOFFSET(pagep));
00072 HOFFSET(pagep) += nbytes;
00073
00074
00075 offset = pagep->inp[indx];
00076 for (cnt = 0; cnt < NUM_ENT(pagep); ++cnt)
00077 if (pagep->inp[cnt] < offset)
00078 pagep->inp[cnt] += nbytes;
00079
00080
00081 --NUM_ENT(pagep);
00082 if (indx != NUM_ENT(pagep))
00083 memmove(&pagep->inp[indx], &pagep->inp[indx + 1],
00084 sizeof(db_indx_t) * (NUM_ENT(pagep) - indx));
00085
00086 return (0);
00087 }
00088
00089
00090
00091
00092
00093
00094
00095
00096 int
00097 CDB___db_pitem(dbc, pagep, indx, nbytes, hdr, data)
00098 DBC *dbc;
00099 PAGE *pagep;
00100 u_int32_t indx;
00101 u_int32_t nbytes;
00102 DBT *hdr, *data;
00103 {
00104 DB *dbp;
00105 BKEYDATA bk;
00106 DBT thdr;
00107 int ret;
00108 u_int8_t *p;
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127 dbp = dbc->dbp;
00128 if (DB_LOGGING(dbc))
00129 if ((ret = CDB___db_addrem_log(dbp->dbenv, dbc->txn,
00130 &LSN(pagep), 0, DB_ADD_DUP, dbp->log_fileid, PGNO(pagep),
00131 (u_int32_t)indx, nbytes, hdr, data, &LSN(pagep))) != 0)
00132 return (ret);
00133
00134 if (hdr == NULL) {
00135 B_TSET(bk.type, B_KEYDATA, 0);
00136 bk.len = data == NULL ? 0 : data->size;
00137
00138 thdr.data = &bk;
00139 thdr.size = SSZA(BKEYDATA, data);
00140 hdr = &thdr;
00141 }
00142
00143
00144 if (indx != NUM_ENT(pagep))
00145 memmove(&pagep->inp[indx + 1], &pagep->inp[indx],
00146 sizeof(db_indx_t) * (NUM_ENT(pagep) - indx));
00147 HOFFSET(pagep) -= nbytes;
00148 pagep->inp[indx] = HOFFSET(pagep);
00149 ++NUM_ENT(pagep);
00150
00151 p = P_ENTRY(pagep, indx);
00152 memcpy(p, hdr->data, hdr->size);
00153 if (data != NULL)
00154 memcpy(p + hdr->size, data->data, data->size);
00155
00156 return (0);
00157 }
00158
00159
00160
00161
00162
00163
00164
00165 int
00166 CDB___db_relink(dbc, add_rem, pagep, new_next, needlock)
00167 DBC *dbc;
00168 u_int32_t add_rem;
00169 PAGE *pagep, **new_next;
00170 int needlock;
00171 {
00172 DB *dbp;
00173 PAGE *np, *pp;
00174 DB_LOCK npl, ppl;
00175 DB_LSN *nlsnp, *plsnp, ret_lsn;
00176 int ret;
00177
00178 ret = 0;
00179 np = pp = NULL;
00180 npl.off = ppl.off = LOCK_INVALID;
00181 nlsnp = plsnp = NULL;
00182 dbp = dbc->dbp;
00183
00184
00185
00186
00187
00188
00189 if (pagep->next_pgno != PGNO_INVALID) {
00190 if (needlock && (ret = CDB___db_lget(dbc,
00191 0, pagep->next_pgno, DB_LOCK_WRITE, 0, &npl)) != 0)
00192 goto err;
00193 if ((ret = CDB_memp_fget(dbp->mpf,
00194 &pagep->next_pgno, 0, &np)) != 0) {
00195 (void)CDB___db_pgerr(dbp, pagep->next_pgno);
00196 goto err;
00197 }
00198 nlsnp = &np->lsn;
00199 }
00200 if (add_rem == DB_REM_PAGE && pagep->prev_pgno != PGNO_INVALID) {
00201 if (needlock && (ret = CDB___db_lget(dbc,
00202 0, pagep->prev_pgno, DB_LOCK_WRITE, 0, &ppl)) != 0)
00203 goto err;
00204 if ((ret = CDB_memp_fget(dbp->mpf,
00205 &pagep->prev_pgno, 0, &pp)) != 0) {
00206 (void)CDB___db_pgerr(dbp, pagep->next_pgno);
00207 goto err;
00208 }
00209 plsnp = &pp->lsn;
00210 }
00211
00212
00213 if (DB_LOGGING(dbc)) {
00214 if ((ret = CDB___db_relink_log(dbp->dbenv, dbc->txn,
00215 &ret_lsn, 0, add_rem, dbp->log_fileid,
00216 pagep->pgno, &pagep->lsn,
00217 pagep->prev_pgno, plsnp, pagep->next_pgno, nlsnp)) != 0)
00218 goto err;
00219 if (np != NULL)
00220 np->lsn = ret_lsn;
00221 if (pp != NULL)
00222 pp->lsn = ret_lsn;
00223 if (add_rem == DB_REM_PAGE)
00224 pagep->lsn = ret_lsn;
00225 }
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 if (np != NULL) {
00236 if (add_rem == DB_ADD_PAGE)
00237 np->prev_pgno = pagep->pgno;
00238 else
00239 np->prev_pgno = pagep->prev_pgno;
00240 if (new_next == NULL)
00241 ret = CDB_memp_fput(dbp->mpf, np, DB_MPOOL_DIRTY);
00242 else {
00243 *new_next = np;
00244 ret = CDB_memp_fset(dbp->mpf, np, DB_MPOOL_DIRTY);
00245 }
00246 if (ret != 0)
00247 goto err;
00248 if (needlock)
00249 (void)__TLPUT(dbc, npl);
00250 } else if (new_next != NULL)
00251 *new_next = NULL;
00252
00253 if (pp != NULL) {
00254 pp->next_pgno = pagep->next_pgno;
00255 if ((ret = CDB_memp_fput(dbp->mpf, pp, DB_MPOOL_DIRTY)) != 0)
00256 goto err;
00257 if (needlock)
00258 (void)__TLPUT(dbc, ppl);
00259 }
00260 return (0);
00261
00262 err: if (np != NULL)
00263 (void)CDB_memp_fput(dbp->mpf, np, 0);
00264 if (needlock && npl.off != LOCK_INVALID)
00265 (void)__TLPUT(dbc, npl);
00266 if (pp != NULL)
00267 (void)CDB_memp_fput(dbp->mpf, pp, 0);
00268 if (needlock && ppl.off != LOCK_INVALID)
00269 (void)__TLPUT(dbc, ppl);
00270 return (ret);
00271 }