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