00001
00002
00003
00004
00005
00006
00007
00008 #include "config.h"
00009
00010 #ifndef lint
00011 static const char revid[] = "$Id: db__upg__opd_8c-source.html,v 1.1 2008/06/08 10:18:21 sebdiaz Exp $";
00012 #endif
00013
00014 #ifndef NO_SYSTEM_INCLUDES
00015 #include <sys/types.h>
00016
00017 #include <errno.h>
00018 #include <string.h>
00019 #endif
00020
00021 #include "db_int.h"
00022 #include "db_page.h"
00023 #include "db_swap.h"
00024 #include "btree.h"
00025 #include "hash.h"
00026 #include "qam.h"
00027
00028 static int __db_build_bi __P((DB *, DB_FH *, PAGE *, PAGE *, u_int32_t, int *));
00029 static int __db_build_ri __P((DB *, DB_FH *, PAGE *, PAGE *, u_int32_t, int *));
00030 static int __db_up_ovref __P((DB *, DB_FH *, db_pgno_t));
00031
00032 #define GET_PAGE(dbp, fhp, pgno, page) { \
00033 if ((ret = CDB___os_seek(dbp->dbenv, \
00034 fhp, (dbp)->pgsize, pgno, 0, 0, DB_OS_SEEK_SET)) != 0) \
00035 goto err; \
00036 if ((ret = CDB___os_read(dbp->dbenv, \
00037 fhp, page, (dbp)->pgsize, &n)) != 0) \
00038 goto err; \
00039 }
00040 #define PUT_PAGE(dbp, fhp, pgno, page) { \
00041 if ((ret = CDB___os_seek(dbp->dbenv, \
00042 fhp, (dbp)->pgsize, pgno, 0, 0, DB_OS_SEEK_SET)) != 0) \
00043 goto err; \
00044 if ((ret = CDB___os_write(dbp->dbenv, \
00045 fhp, page, (dbp)->pgsize, &n)) != 0) \
00046 goto err; \
00047 }
00048
00049
00050
00051
00052
00053
00054
00055 int
00056 CDB___db_31_offdup(dbp, real_name, fhp, sorted, pgnop)
00057 DB *dbp;
00058 char *real_name;
00059 DB_FH *fhp;
00060 int sorted;
00061 db_pgno_t *pgnop;
00062 {
00063 PAGE *ipage, *page;
00064 db_indx_t indx;
00065 db_pgno_t cur_cnt, i, next_cnt, pgno, *pgno_cur, pgno_last;
00066 db_pgno_t *pgno_next, pgno_max, *tmp;
00067 db_recno_t nrecs;
00068 size_t n;
00069 int level, nomem, ret;
00070
00071 ipage = page = NULL;
00072 pgno_cur = pgno_next = NULL;
00073
00074
00075 if ((ret = CDB___os_malloc(dbp->dbenv, dbp->pgsize, NULL, &page)) != 0)
00076 goto err;
00077
00078
00079
00080
00081
00082
00083
00084 for (nrecs = 0, cur_cnt = pgno_max = 0,
00085 pgno = *pgnop; pgno != PGNO_INVALID;) {
00086 if (pgno_max == cur_cnt) {
00087 pgno_max += 20;
00088 if ((ret = CDB___os_realloc(dbp->dbenv, pgno_max *
00089 sizeof(db_pgno_t), NULL, &pgno_cur)) != 0)
00090 goto err;
00091 }
00092 pgno_cur[cur_cnt++] = pgno;
00093
00094 GET_PAGE(dbp, fhp, pgno, page);
00095 nrecs += NUM_ENT(page);
00096 LEVEL(page) = LEAFLEVEL;
00097 TYPE_SET(page, sorted ? P_LDUP : P_LRECNO);
00098
00099
00100
00101
00102 ZERO_LSN(LSN(page));
00103 PUT_PAGE(dbp, fhp, pgno, page);
00104
00105 pgno = NEXT_PGNO(page);
00106 }
00107
00108
00109 if (cur_cnt > 1) {
00110
00111
00112
00113
00114
00115 if ((ret = CDB___os_malloc(dbp->dbenv,
00116 cur_cnt * sizeof(db_pgno_t), NULL, &pgno_next)) != 0)
00117 goto err;
00118
00119
00120 if ((ret = CDB___db_lastpgno(dbp, real_name, fhp, &pgno_last)) != 0)
00121 goto err;
00122
00123
00124 if ((ret = CDB___os_malloc(dbp->dbenv,
00125 dbp->pgsize, NULL, &ipage)) != 0)
00126 goto err;
00127 PGNO(ipage) = PGNO_INVALID;
00128 }
00129
00130
00131
00132
00133
00134 for (level = LEAFLEVEL + 1; cur_cnt > 1; ++level) {
00135 for (indx = 0, i = next_cnt = 0; i < cur_cnt;) {
00136 if (indx == 0) {
00137 P_INIT(ipage, dbp->pgsize, pgno_last,
00138 PGNO_INVALID, PGNO_INVALID,
00139 level, sorted ? P_IBTREE : P_IRECNO, 0);
00140 ZERO_LSN(LSN(ipage));
00141
00142 pgno_next[next_cnt++] = pgno_last++;
00143 }
00144
00145 GET_PAGE(dbp, fhp, pgno_cur[i], page);
00146
00147
00148
00149
00150
00151
00152
00153
00154 nomem = 0;
00155 if (sorted) {
00156 if ((ret = __db_build_bi(
00157 dbp, fhp, ipage, page, indx, &nomem)) != 0)
00158 goto err;
00159 } else
00160 if ((ret = __db_build_ri(
00161 dbp, fhp, ipage, page, indx, &nomem)) != 0)
00162 goto err;
00163 if (nomem) {
00164 indx = 0;
00165 PUT_PAGE(dbp, fhp, PGNO(ipage), ipage);
00166 } else {
00167 ++indx;
00168 ++NUM_ENT(ipage);
00169 ++i;
00170 }
00171 }
00172
00173
00174
00175
00176
00177 if (next_cnt == 1)
00178 RE_NREC_SET(ipage, nrecs);
00179 PUT_PAGE(dbp, fhp, PGNO(ipage), ipage);
00180
00181
00182 cur_cnt = next_cnt;
00183 tmp = pgno_cur;
00184 pgno_cur = pgno_next;
00185 pgno_next = tmp;
00186 }
00187
00188 *pgnop = pgno_cur[0];
00189
00190 err: if (pgno_cur != NULL)
00191 CDB___os_free(pgno_cur, 0);
00192 if (pgno_next != NULL)
00193 CDB___os_free(pgno_next, 0);
00194 if (ipage != NULL)
00195 CDB___os_free(ipage, dbp->pgsize);
00196 if (page != NULL)
00197 CDB___os_free(page, dbp->pgsize);
00198
00199 return (ret);
00200 }
00201
00202
00203
00204
00205
00206 static int
00207 __db_build_bi(dbp, fhp, ipage, page, indx, nomemp)
00208 DB *dbp;
00209 DB_FH *fhp;
00210 PAGE *ipage, *page;
00211 u_int32_t indx;
00212 int *nomemp;
00213 {
00214 BINTERNAL bi, *child_bi;
00215 BKEYDATA *child_bk;
00216 u_int8_t *p;
00217 int ret;
00218
00219 switch (TYPE(page)) {
00220 case P_IBTREE:
00221 child_bi = GET_BINTERNAL(page, 0);
00222 if (P_FREESPACE(ipage) < BINTERNAL_PSIZE(child_bi->len)) {
00223 *nomemp = 1;
00224 return (0);
00225 }
00226 ipage->inp[indx] =
00227 HOFFSET(ipage) -= BINTERNAL_SIZE(child_bi->len);
00228 p = P_ENTRY(ipage, indx);
00229
00230 bi.len = child_bi->len;
00231 B_TSET(bi.type, child_bi->type, 0);
00232 bi.pgno = PGNO(page);
00233 bi.nrecs = CDB___bam_total(page);
00234 memcpy(p, &bi, SSZA(BINTERNAL, data));
00235 p += SSZA(BINTERNAL, data);
00236 memcpy(p, child_bi->data, child_bi->len);
00237
00238
00239 if (B_TYPE(child_bi->type) == B_OVERFLOW)
00240 if ((ret = __db_up_ovref(dbp, fhp,
00241 ((BOVERFLOW *)(child_bi->data))->pgno)) != 0)
00242 return (ret);
00243 break;
00244 case P_LDUP:
00245 child_bk = GET_BKEYDATA(page, 0);
00246 switch (B_TYPE(child_bk->type)) {
00247 case B_KEYDATA:
00248 if (P_FREESPACE(ipage) <
00249 BINTERNAL_PSIZE(child_bk->len)) {
00250 *nomemp = 1;
00251 return (0);
00252 }
00253 ipage->inp[indx] =
00254 HOFFSET(ipage) -= BINTERNAL_SIZE(child_bk->len);
00255 p = P_ENTRY(ipage, indx);
00256
00257 bi.len = child_bk->len;
00258 B_TSET(bi.type, child_bk->type, 0);
00259 bi.pgno = PGNO(page);
00260 bi.nrecs = CDB___bam_total(page);
00261 memcpy(p, &bi, SSZA(BINTERNAL, data));
00262 p += SSZA(BINTERNAL, data);
00263 memcpy(p, child_bk->data, child_bk->len);
00264 break;
00265 case B_OVERFLOW:
00266 if (P_FREESPACE(ipage) <
00267 BINTERNAL_PSIZE(BOVERFLOW_SIZE)) {
00268 *nomemp = 1;
00269 return (0);
00270 }
00271 ipage->inp[indx] =
00272 HOFFSET(ipage) -= BINTERNAL_SIZE(BOVERFLOW_SIZE);
00273 p = P_ENTRY(ipage, indx);
00274
00275 bi.len = BOVERFLOW_SIZE;
00276 B_TSET(bi.type, child_bk->type, 0);
00277 bi.pgno = PGNO(page);
00278 bi.nrecs = CDB___bam_total(page);
00279 memcpy(p, &bi, SSZA(BINTERNAL, data));
00280 p += SSZA(BINTERNAL, data);
00281 memcpy(p, child_bk, BOVERFLOW_SIZE);
00282
00283
00284 if ((ret = __db_up_ovref(dbp, fhp,
00285 ((BOVERFLOW *)child_bk)->pgno)) != 0)
00286 return (ret);
00287 break;
00288 default:
00289 return (CDB___db_pgfmt(dbp, PGNO(page)));
00290 }
00291 break;
00292 default:
00293 return (CDB___db_pgfmt(dbp, PGNO(page)));
00294 }
00295
00296 return (0);
00297 }
00298
00299
00300
00301
00302
00303 static int
00304 __db_build_ri(dbp, fhp, ipage, page, indx, nomemp)
00305 DB *dbp;
00306 DB_FH *fhp;
00307 PAGE *ipage, *page;
00308 u_int32_t indx;
00309 int *nomemp;
00310 {
00311 RINTERNAL ri;
00312
00313 COMPQUIET(dbp, NULL);
00314 COMPQUIET(fhp, NULL);
00315
00316 if (P_FREESPACE(ipage) < RINTERNAL_PSIZE) {
00317 *nomemp = 1;
00318 return (0);
00319 }
00320
00321 ri.pgno = PGNO(page);
00322 ri.nrecs = CDB___bam_total(page);
00323 ipage->inp[indx] = HOFFSET(ipage) -= RINTERNAL_SIZE;
00324 memcpy(P_ENTRY(ipage, indx), &ri, RINTERNAL_SIZE);
00325
00326 return (0);
00327 }
00328
00329
00330
00331
00332
00333 static int
00334 __db_up_ovref(dbp, fhp, pgno)
00335 DB *dbp;
00336 DB_FH *fhp;
00337 db_pgno_t pgno;
00338 {
00339 PAGE *page;
00340 size_t n;
00341 int ret;
00342
00343
00344 if ((ret = CDB___os_malloc(dbp->dbenv, dbp->pgsize, NULL, &page)) != 0)
00345 return (ret);
00346
00347 GET_PAGE(dbp, fhp, pgno, page);
00348 ++OV_REF(page);
00349 PUT_PAGE(dbp, fhp, pgno, page);
00350
00351 err: CDB___os_free(page, dbp->pgsize);
00352
00353 return (ret);
00354 }