#include "db_config.h"
#include "db_int.h"
#include "dbinc/db_page.h"
#include "dbinc/hash.h"
#include "dbinc/db_upgrade.h"
int
__ham_30_hashmeta(dbp, real_name, obuf)
DB *dbp;
char *real_name;
u_int8_t *obuf;
{
DB_ENV *dbenv;
HASHHDR *oldmeta;
HMETA30 newmeta;
u_int32_t *o_spares, *n_spares;
u_int32_t fillf, i, maxb, max_entry, nelem;
int ret;
dbenv = dbp->dbenv;
memset(&newmeta, 0, sizeof(newmeta));
oldmeta = (HASHHDR *)obuf;
newmeta.dbmeta.lsn = oldmeta->lsn;
newmeta.dbmeta.pgno = oldmeta->pgno;
newmeta.dbmeta.magic = oldmeta->magic;
newmeta.dbmeta.version = 6;
newmeta.dbmeta.pagesize = oldmeta->pagesize;
newmeta.dbmeta.type = P_HASHMETA;
newmeta.dbmeta.flags = oldmeta->flags;
newmeta.dbmeta.free = oldmeta->last_freed;
newmeta.max_bucket = oldmeta->max_bucket;
newmeta.high_mask = oldmeta->high_mask;
newmeta.low_mask = oldmeta->low_mask;
newmeta.ffactor = oldmeta->ffactor;
newmeta.nelem = oldmeta->nelem;
newmeta.h_charkey = oldmeta->h_charkey;
nelem = newmeta.nelem;
fillf = newmeta.ffactor;
maxb = newmeta.max_bucket;
if ((fillf != 0 && fillf * maxb < 2 * nelem) ||
(fillf == 0 && nelem > 0x8000000))
newmeta.nelem = 0;
o_spares = oldmeta->spares;
n_spares = newmeta.spares;
max_entry = __db_log2(maxb + 1);
n_spares[0] = 1;
for (i = 1; i < NCACHED && i <= max_entry; i++)
n_spares[i] = 1 + o_spares[i - 1];
if ((ret = __os_fileid(dbenv, real_name, 1, newmeta.dbmeta.uid)) != 0)
return (ret);
memcpy(oldmeta, &newmeta, sizeof(newmeta));
return (0);
}
int
__ham_30_sizefix(dbp, fhp, realname, metabuf)
DB *dbp;
DB_FH *fhp;
char *realname;
u_int8_t *metabuf;
{
u_int8_t buf[DB_MAX_PGSIZE];
DB_ENV *dbenv;
HMETA30 *meta;
db_pgno_t last_actual, last_desired;
int ret;
size_t nw;
u_int32_t pagesize;
dbenv = dbp->dbenv;
memset(buf, 0, DB_MAX_PGSIZE);
meta = (HMETA30 *)metabuf;
pagesize = meta->dbmeta.pagesize;
dbp->pgsize = pagesize;
if ((ret = __db_lastpgno(dbp, realname, fhp, &last_actual)) != 0)
return (ret);
last_desired = BS_TO_PAGE(meta->high_mask, meta->spares);
if (last_desired > last_actual) {
if ((ret = __os_seek(
dbenv, fhp, last_desired, pagesize, 0)) != 0)
return (ret);
if ((ret = __os_write(dbenv, fhp, buf, pagesize, &nw)) != 0)
return (ret);
}
return (0);
}
int
__ham_31_hashmeta(dbp, real_name, flags, fhp, h, dirtyp)
DB *dbp;
char *real_name;
u_int32_t flags;
DB_FH *fhp;
PAGE *h;
int *dirtyp;
{
HMETA31 *newmeta;
HMETA30 *oldmeta;
COMPQUIET(dbp, NULL);
COMPQUIET(real_name, NULL);
COMPQUIET(fhp, NULL);
newmeta = (HMETA31 *)h;
oldmeta = (HMETA30 *)h;
memmove(newmeta->spares, oldmeta->spares, sizeof(oldmeta->spares));
newmeta->h_charkey = oldmeta->h_charkey;
newmeta->nelem = oldmeta->nelem;
newmeta->ffactor = oldmeta->ffactor;
newmeta->low_mask = oldmeta->low_mask;
newmeta->high_mask = oldmeta->high_mask;
newmeta->max_bucket = oldmeta->max_bucket;
memmove(newmeta->dbmeta.uid,
oldmeta->dbmeta.uid, sizeof(oldmeta->dbmeta.uid));
newmeta->dbmeta.flags = oldmeta->dbmeta.flags;
newmeta->dbmeta.record_count = 0;
newmeta->dbmeta.key_count = 0;
ZERO_LSN(newmeta->dbmeta.unused3);
newmeta->dbmeta.version = 7;
if (LF_ISSET(DB_DUPSORT))
F_SET(&newmeta->dbmeta, DB_HASH_DUPSORT);
*dirtyp = 1;
return (0);
}
int
__ham_31_hash(dbp, real_name, flags, fhp, h, dirtyp)
DB *dbp;
char *real_name;
u_int32_t flags;
DB_FH *fhp;
PAGE *h;
int *dirtyp;
{
HKEYDATA *hk;
db_pgno_t pgno, tpgno;
db_indx_t indx;
int ret;
COMPQUIET(flags, 0);
ret = 0;
for (indx = 0; indx < NUM_ENT(h); indx += 2) {
hk = (HKEYDATA *)H_PAIRDATA(dbp, h, indx);
if (HPAGE_PTYPE(hk) == H_OFFDUP) {
memcpy(&pgno, HOFFDUP_PGNO(hk), sizeof(db_pgno_t));
tpgno = pgno;
if ((ret = __db_31_offdup(dbp, real_name, fhp,
LF_ISSET(DB_DUPSORT) ? 1 : 0, &tpgno)) != 0)
break;
if (pgno != tpgno) {
*dirtyp = 1;
memcpy(HOFFDUP_PGNO(hk),
&tpgno, sizeof(db_pgno_t));
}
}
}
return (ret);
}
int
__ham_46_hashmeta(dbp, real_name, flags, fhp, h, dirtyp)
DB *dbp;
char *real_name;
u_int32_t flags;
DB_FH *fhp;
PAGE *h;
int *dirtyp;
{
HMETA33 *newmeta;
COMPQUIET(dbp, NULL);
COMPQUIET(real_name, NULL);
COMPQUIET(flags, 0);
COMPQUIET(fhp, NULL);
newmeta = (HMETA33 *)h;
newmeta->dbmeta.version = 9;
*dirtyp = 1;
return (0);
}
int
__ham_46_hash(dbp, real_name, flags, fhp, h, dirtyp)
DB *dbp;
char *real_name;
u_int32_t flags;
DB_FH *fhp;
PAGE *h;
int *dirtyp;
{
COMPQUIET(real_name, NULL);
COMPQUIET(flags, 0);
COMPQUIET(fhp, NULL);
*dirtyp = 1;
return (__ham_sort_page(dbp, NULL, NULL, h));
}