summaryrefslogtreecommitdiffstats
path: root/debian/htdig/htdig-3.2.0b6/db/hash_upgrade.c
diff options
context:
space:
mode:
Diffstat (limited to 'debian/htdig/htdig-3.2.0b6/db/hash_upgrade.c')
-rw-r--r--debian/htdig/htdig-3.2.0b6/db/hash_upgrade.c206
1 files changed, 206 insertions, 0 deletions
diff --git a/debian/htdig/htdig-3.2.0b6/db/hash_upgrade.c b/debian/htdig/htdig-3.2.0b6/db/hash_upgrade.c
new file mode 100644
index 00000000..ace73719
--- /dev/null
+++ b/debian/htdig/htdig-3.2.0b6/db/hash_upgrade.c
@@ -0,0 +1,206 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 1997, 1998, 1999
+ * Sleepycat Software. All rights reserved.
+ */
+#include "db_config.h"
+
+#ifndef lint
+static const char sccsid[] = "@(#)hash_upgrade.c 11.7 (Sleepycat) 10/20/99";
+#endif /* not lint */
+
+#ifndef NO_SYSTEM_INCLUDES
+#include <sys/types.h>
+
+#include <errno.h>
+#include <limits.h>
+#include <string.h>
+#endif
+
+#include "db_int.h"
+#include "db_page.h"
+#include "db_swap.h"
+#include "hash.h"
+
+static int CDB___ham_upgrade5 __P((DB *, int, char *, DB_FH *));
+
+/*
+ * CDB___ham_upgrade --
+ * Upgrade Hash databases.
+ *
+ * PUBLIC: int CDB___ham_upgrade __P((DB *, int, char *, DB_FH *, char *));
+ */
+int
+CDB___ham_upgrade(dbp, swapped, real_name, fhp, mbuf)
+ DB *dbp;
+ int swapped;
+ char *real_name, *mbuf;
+ DB_FH *fhp;
+{
+ DB_ENV *dbenv;
+ int ret;
+
+ dbenv = dbp->dbenv;
+
+ /* Check the version. */
+ switch (((DBMETA *)mbuf)->version) {
+ case 4:
+ case 5:
+ if ((ret = CDB___ham_upgrade5(dbp, swapped, real_name, fhp)) != 0)
+ return (ret);
+ /* FALLTHROUGH */
+ case 6:
+ break;
+ default:
+ CDB___db_err(dbenv, "%s: unsupported hash version: %lu",
+ real_name, (u_long)((DBMETA *)mbuf)->version);
+ return (DB_OLD_VERSION);
+ }
+ return (0);
+}
+
+/*
+ * CDB___ham_upgrade5 --
+ * Upgrade the database from version 4/5 to version 6.
+ */
+static int
+CDB___ham_upgrade5(dbp, swapped, real_name, fhp)
+ DB *dbp;
+ int swapped;
+ char *real_name;
+ DB_FH *fhp;
+{
+ DB_ENV *dbenv;
+ ssize_t n;
+ u_int32_t *o_spares, *n_spares, version;
+ u_int32_t fillf, maxb, nelem;
+ int i, non_zero, ret;
+ u_int8_t nbuf[256], *new, obuf[256];
+
+ dbenv = dbp->dbenv;
+
+ if (dbp->db_feedback != NULL)
+ dbp->db_feedback(dbp, DB_UPGRADE, 0);
+
+ /*
+ * Seek to the beginning of the file and read the metadata page. We
+ * read 256 bytes, which is larger than any access method's metadata
+ * page.
+ */
+ if ((ret = CDB___os_seek(fhp, 0, 0, 0, 0, DB_OS_SEEK_SET)) != 0)
+ return (ret);
+ if ((ret = CDB___os_read(fhp, obuf, sizeof(obuf), &n)) != 0)
+ return (ret);
+
+ /*
+ * Upgrade a Hash meta-data page.
+ * Version 5: byte range: Version 6: byte range:
+ * lsn 00-07 lsn 00-07
+ * pgno 08-11 pgno 08-11
+ * magic 12-15 magic 12-15
+ * version 16-19 version 16-19
+ * pagesize 20-23 pagesize 20-23
+ * ovfl_point 24-27 unused 24
+ * type 25
+ * unused 26-27
+ * last_freed 28-31 free 28-31
+ * max_bucket 32-35 flags 32-35
+ * high_mask 36-39 uid 36-55
+ * low_mask 40-43 max_bucket 56-59
+ * ffactor 44-47 high_mask 60-63
+ * nelem 48-51 low_mask 64-67
+ * h_charkey 52-55 ffactor 68-71
+ * flags 56-59 nelem 72-75
+ * spares 60-187 h_charkey 76-79
+ * uid 188-207 spares 80-207
+ *
+ */
+
+ /*
+ * The first 32 bytes are similar. The only change is the version
+ * and that we removed the ovfl_point and have the page type now.
+ */
+ memcpy(nbuf, obuf, 32);
+
+ /* Update the version. */
+ version = 6;
+ if (swapped)
+ M_32_SWAP(version);
+ memcpy(nbuf + 16, &version, sizeof(u_int32_t));
+
+ /* Assign unused and type fields. */
+ new = nbuf + 24;
+ *new++ = '\0';
+ *new++ = P_HASHMETA;
+ *new++ = '\0';
+ *new = '\0';
+
+ /* Move flags */
+ memcpy(nbuf + 32, obuf + 56, 4);
+
+ /* Copy: max_bucket, high_mask, low-mask, ffactor, nelem, h_charkey */
+ memcpy(nbuf + 56, obuf + 32, 24);
+
+ /*
+ * There was a bug in 2.X versions where the nelem could go negative.
+ * In general, this is considered "bad." If it does go negative
+ * (that is, very large and positive), we'll die trying to dump and
+ * load this database. So, let's see if we can fix it here.
+ */
+ memcpy(&nelem, nbuf + 72, sizeof(u_int32_t));
+ memcpy(&fillf, nbuf + 68, sizeof(u_int32_t));
+ memcpy(&maxb, nbuf + 56, sizeof(u_int32_t));
+ if (swapped) {
+ M_32_SWAP(nelem);
+ M_32_SWAP(fillf);
+ M_32_SWAP(maxb);
+ }
+
+ if ((fillf != 0 && fillf * maxb < 2 * nelem) ||
+ (fillf == 0 && nelem > 0x8000000)) {
+ nelem = 0;
+ memcpy(nbuf + 72, &nelem, sizeof(u_int32_t));
+ }
+
+ /*
+ * We now have to convert the spares array. The old spares array
+ * contained the total number of extra pages allocated prior to
+ * the bucket that begins the next doubling. The new spares array
+ * contains the page number of the first bucket in the next doubling
+ * MINUS the bucket number of that bucket.
+ */
+ o_spares = (u_int32_t *)(obuf + 60);
+ n_spares = (u_int32_t *)(nbuf + 80);
+ non_zero = 0;
+ n_spares[0] = 1;
+ for (i = 1; i < NCACHED; i++) {
+ if (swapped)
+ M_32_SWAP(o_spares[i -1]);
+ non_zero = non_zero || o_spares[i - 1] != 0;
+ if (o_spares[i - 1] == 0 && non_zero)
+ n_spares[i] = 0;
+ else
+ n_spares[i] = 1 + o_spares[i - 1];
+ }
+
+ if (swapped)
+ for (i = 0; i < NCACHED; i++)
+ M_32_SWAP(n_spares[i]);
+
+ /* Replace the unique ID. */
+ if ((ret = CDB___os_fileid(dbenv, real_name, 1, nbuf + 36)) != 0)
+ return (ret);
+
+ if ((ret = CDB___os_seek(fhp, 0, 0, 0, 1, DB_OS_SEEK_SET)) != 0)
+ return (ret);
+ if ((ret = CDB___os_write(fhp, nbuf, 256, &n)) != 0)
+ return (ret);
+ if ((ret = CDB___os_fsync(fhp)) != 0)
+ return (ret);
+
+ if (dbp->db_feedback != NULL)
+ dbp->db_feedback(dbp, DB_UPGRADE, 100);
+
+ return (0);
+}