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/hash.h"
00021 #include "dbinc/db_upgrade.h"
00022
00023
00024
00025
00026
00027
00028
00029 int
00030 __ham_30_hashmeta(dbp, real_name, obuf)
00031 DB *dbp;
00032 char *real_name;
00033 u_int8_t *obuf;
00034 {
00035 DB_ENV *dbenv;
00036 HASHHDR *oldmeta;
00037 HMETA30 newmeta;
00038 u_int32_t *o_spares, *n_spares;
00039 u_int32_t fillf, i, maxb, max_entry, nelem;
00040 int ret;
00041
00042 dbenv = dbp->dbenv;
00043 memset(&newmeta, 0, sizeof(newmeta));
00044
00045 oldmeta = (HASHHDR *)obuf;
00046
00047
00048
00049
00050
00051
00052 newmeta.dbmeta.lsn = oldmeta->lsn;
00053 newmeta.dbmeta.pgno = oldmeta->pgno;
00054 newmeta.dbmeta.magic = oldmeta->magic;
00055 newmeta.dbmeta.version = 6;
00056 newmeta.dbmeta.pagesize = oldmeta->pagesize;
00057 newmeta.dbmeta.type = P_HASHMETA;
00058
00059
00060 newmeta.dbmeta.flags = oldmeta->flags;
00061
00062
00063 newmeta.dbmeta.free = oldmeta->last_freed;
00064
00065
00066 newmeta.max_bucket = oldmeta->max_bucket;
00067 newmeta.high_mask = oldmeta->high_mask;
00068 newmeta.low_mask = oldmeta->low_mask;
00069 newmeta.ffactor = oldmeta->ffactor;
00070 newmeta.nelem = oldmeta->nelem;
00071 newmeta.h_charkey = oldmeta->h_charkey;
00072
00073
00074
00075
00076
00077
00078
00079 nelem = newmeta.nelem;
00080 fillf = newmeta.ffactor;
00081 maxb = newmeta.max_bucket;
00082
00083 if ((fillf != 0 && fillf * maxb < 2 * nelem) ||
00084 (fillf == 0 && nelem > 0x8000000))
00085 newmeta.nelem = 0;
00086
00087
00088
00089
00090
00091
00092
00093
00094 o_spares = oldmeta->spares;
00095 n_spares = newmeta.spares;
00096 max_entry = __db_log2(maxb + 1);
00097 n_spares[0] = 1;
00098 for (i = 1; i < NCACHED && i <= max_entry; i++)
00099 n_spares[i] = 1 + o_spares[i - 1];
00100
00101
00102 if ((ret = __os_fileid(dbenv, real_name, 1, newmeta.dbmeta.uid)) != 0)
00103 return (ret);
00104
00105
00106 memcpy(oldmeta, &newmeta, sizeof(newmeta));
00107
00108 return (0);
00109 }
00110
00111
00112
00113
00114
00115
00116
00117
00118 int
00119 __ham_30_sizefix(dbp, fhp, realname, metabuf)
00120 DB *dbp;
00121 DB_FH *fhp;
00122 char *realname;
00123 u_int8_t *metabuf;
00124 {
00125 u_int8_t buf[DB_MAX_PGSIZE];
00126 DB_ENV *dbenv;
00127 HMETA30 *meta;
00128 db_pgno_t last_actual, last_desired;
00129 int ret;
00130 size_t nw;
00131 u_int32_t pagesize;
00132
00133 dbenv = dbp->dbenv;
00134 memset(buf, 0, DB_MAX_PGSIZE);
00135
00136 meta = (HMETA30 *)metabuf;
00137 pagesize = meta->dbmeta.pagesize;
00138
00139
00140
00141
00142
00143 dbp->pgsize = pagesize;
00144 if ((ret = __db_lastpgno(dbp, realname, fhp, &last_actual)) != 0)
00145 return (ret);
00146
00147
00148
00149
00150
00151 last_desired = BS_TO_PAGE(meta->high_mask, meta->spares);
00152
00153
00154
00155
00156
00157 if (last_desired > last_actual) {
00158 if ((ret = __os_seek(dbenv,
00159 fhp, pagesize, last_desired, 0, 0, DB_OS_SEEK_SET)) != 0)
00160 return (ret);
00161 if ((ret = __os_write(dbenv, fhp, buf, pagesize, &nw)) != 0)
00162 return (ret);
00163 }
00164
00165 return (0);
00166 }
00167
00168
00169
00170
00171
00172
00173
00174
00175 int
00176 __ham_31_hashmeta(dbp, real_name, flags, fhp, h, dirtyp)
00177 DB *dbp;
00178 char *real_name;
00179 u_int32_t flags;
00180 DB_FH *fhp;
00181 PAGE *h;
00182 int *dirtyp;
00183 {
00184 HMETA31 *newmeta;
00185 HMETA30 *oldmeta;
00186
00187 COMPQUIET(dbp, NULL);
00188 COMPQUIET(real_name, NULL);
00189 COMPQUIET(fhp, NULL);
00190
00191 newmeta = (HMETA31 *)h;
00192 oldmeta = (HMETA30 *)h;
00193
00194
00195
00196
00197
00198 memmove(newmeta->spares, oldmeta->spares, sizeof(oldmeta->spares));
00199 newmeta->h_charkey = oldmeta->h_charkey;
00200 newmeta->nelem = oldmeta->nelem;
00201 newmeta->ffactor = oldmeta->ffactor;
00202 newmeta->low_mask = oldmeta->low_mask;
00203 newmeta->high_mask = oldmeta->high_mask;
00204 newmeta->max_bucket = oldmeta->max_bucket;
00205 memmove(newmeta->dbmeta.uid,
00206 oldmeta->dbmeta.uid, sizeof(oldmeta->dbmeta.uid));
00207 newmeta->dbmeta.flags = oldmeta->dbmeta.flags;
00208 newmeta->dbmeta.record_count = 0;
00209 newmeta->dbmeta.key_count = 0;
00210 ZERO_LSN(newmeta->dbmeta.unused3);
00211
00212
00213 newmeta->dbmeta.version = 7;
00214
00215
00216 if (LF_ISSET(DB_DUPSORT))
00217 F_SET(&newmeta->dbmeta, DB_HASH_DUPSORT);
00218
00219 *dirtyp = 1;
00220 return (0);
00221 }
00222
00223
00224
00225
00226
00227
00228
00229
00230 int
00231 __ham_31_hash(dbp, real_name, flags, fhp, h, dirtyp)
00232 DB *dbp;
00233 char *real_name;
00234 u_int32_t flags;
00235 DB_FH *fhp;
00236 PAGE *h;
00237 int *dirtyp;
00238 {
00239 HKEYDATA *hk;
00240 db_pgno_t pgno, tpgno;
00241 db_indx_t indx;
00242 int ret;
00243
00244 COMPQUIET(flags, 0);
00245
00246 ret = 0;
00247 for (indx = 0; indx < NUM_ENT(h); indx += 2) {
00248 hk = (HKEYDATA *)H_PAIRDATA(dbp, h, indx);
00249 if (HPAGE_PTYPE(hk) == H_OFFDUP) {
00250 memcpy(&pgno, HOFFDUP_PGNO(hk), sizeof(db_pgno_t));
00251 tpgno = pgno;
00252 if ((ret = __db_31_offdup(dbp, real_name, fhp,
00253 LF_ISSET(DB_DUPSORT) ? 1 : 0, &tpgno)) != 0)
00254 break;
00255 if (pgno != tpgno) {
00256 *dirtyp = 1;
00257 memcpy(HOFFDUP_PGNO(hk),
00258 &tpgno, sizeof(db_pgno_t));
00259 }
00260 }
00261 }
00262
00263 return (ret);
00264 }