~ubuntu-branches/ubuntu/maverick/evolution-data-server/maverick-proposed

« back to all changes in this revision

Viewing changes to libdb/hash/hash_upgrade.c

  • Committer: Bazaar Package Importer
  • Author(s): Didier Roche
  • Date: 2010-05-17 17:02:06 UTC
  • mfrom: (1.1.79 upstream) (1.6.12 experimental)
  • Revision ID: james.westby@ubuntu.com-20100517170206-4ufr52vwrhh26yh0
Tags: 2.30.1-1ubuntu1
* Merge from debian experimental. Remaining change:
  (LP: #42199, #229669, #173703, #360344, #508494)
  + debian/control:
    - add Vcs-Bzr tag
    - don't use libgnome
    - Use Breaks instead of Conflicts against evolution 2.25 and earlier.
  + debian/evolution-data-server.install,
    debian/patches/45_libcamel_providers_version.patch:
    - use the upstream versioning, not a Debian-specific one 
  + debian/libedata-book1.2-dev.install, debian/libebackend-1.2-dev.install,
    debian/libcamel1.2-dev.install, debian/libedataserverui1.2-dev.install:
    - install html documentation
  + debian/rules:
    - don't build documentation it's shipped with the tarball

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*-
2
 
 * See the file LICENSE for redistribution information.
3
 
 *
4
 
 * Copyright (c) 1996-2002
5
 
 *      Sleepycat Software.  All rights reserved.
6
 
 */
7
 
#include "db_config.h"
8
 
 
9
 
#ifndef lint
10
 
static const char revid[] = "$Id$";
11
 
#endif /* not lint */
12
 
 
13
 
#ifndef NO_SYSTEM_INCLUDES
14
 
#include <sys/types.h>
15
 
 
16
 
#include <limits.h>
17
 
#include <string.h>
18
 
#endif
19
 
 
20
 
#include "db_int.h"
21
 
#include "dbinc/db_page.h"
22
 
#include "dbinc/hash.h"
23
 
#include "dbinc/db_upgrade.h"
24
 
 
25
 
/*
26
 
 * __ham_30_hashmeta --
27
 
 *      Upgrade the database from version 4/5 to version 6.
28
 
 *
29
 
 * PUBLIC: int __ham_30_hashmeta __P((DB *, char *, u_int8_t *));
30
 
 */
31
 
int
32
 
__ham_30_hashmeta(dbp, real_name, obuf)
33
 
        DB *dbp;
34
 
        char *real_name;
35
 
        u_int8_t *obuf;
36
 
{
37
 
        DB_ENV *dbenv;
38
 
        HASHHDR *oldmeta;
39
 
        HMETA30 newmeta;
40
 
        u_int32_t *o_spares, *n_spares;
41
 
        u_int32_t fillf, maxb, nelem;
42
 
        int i, max_entry, ret;
43
 
 
44
 
        dbenv = dbp->dbenv;
45
 
        memset(&newmeta, 0, sizeof(newmeta));
46
 
 
47
 
        oldmeta = (HASHHDR *)obuf;
48
 
 
49
 
        /*
50
 
         * The first 32 bytes are similar.  The only change is the version
51
 
         * and that we removed the ovfl_point and have the page type now.
52
 
         */
53
 
 
54
 
        newmeta.dbmeta.lsn = oldmeta->lsn;
55
 
        newmeta.dbmeta.pgno = oldmeta->pgno;
56
 
        newmeta.dbmeta.magic = oldmeta->magic;
57
 
        newmeta.dbmeta.version = 6;
58
 
        newmeta.dbmeta.pagesize = oldmeta->pagesize;
59
 
        newmeta.dbmeta.type = P_HASHMETA;
60
 
 
61
 
        /* Move flags */
62
 
        newmeta.dbmeta.flags = oldmeta->flags;
63
 
 
64
 
        /* Copy the free list, which has changed its name but works the same. */
65
 
        newmeta.dbmeta.free = oldmeta->last_freed;
66
 
 
67
 
        /* Copy: max_bucket, high_mask, low-mask, ffactor, nelem, h_charkey */
68
 
        newmeta.max_bucket = oldmeta->max_bucket;
69
 
        newmeta.high_mask = oldmeta->high_mask;
70
 
        newmeta.low_mask = oldmeta->low_mask;
71
 
        newmeta.ffactor = oldmeta->ffactor;
72
 
        newmeta.nelem = oldmeta->nelem;
73
 
        newmeta.h_charkey = oldmeta->h_charkey;
74
 
 
75
 
        /*
76
 
         * There was a bug in 2.X versions where the nelem could go negative.
77
 
         * In general, this is considered "bad."  If it does go negative
78
 
         * (that is, very large and positive), we'll die trying to dump and
79
 
         * load this database.  So, let's see if we can fix it here.
80
 
         */
81
 
        nelem = newmeta.nelem;
82
 
        fillf = newmeta.ffactor;
83
 
        maxb = newmeta.max_bucket;
84
 
 
85
 
        if ((fillf != 0 && fillf * maxb < 2 * nelem) ||
86
 
            (fillf == 0 && nelem > 0x8000000))
87
 
                newmeta.nelem = 0;
88
 
 
89
 
        /*
90
 
         * We now have to convert the spares array.  The old spares array
91
 
         * contained the total number of extra pages allocated prior to
92
 
         * the bucket that begins the next doubling.  The new spares array
93
 
         * contains the page number of the first bucket in the next doubling
94
 
         * MINUS the bucket number of that bucket.
95
 
         */
96
 
        o_spares = oldmeta->spares;
97
 
        n_spares = newmeta.spares;
98
 
        max_entry = __db_log2(maxb + 1);   /* highest spares entry in use */
99
 
        n_spares[0] = 1;
100
 
        for (i = 1; i < NCACHED && i <= max_entry; i++)
101
 
                n_spares[i] = 1 + o_spares[i - 1];
102
 
 
103
 
                                        /* Replace the unique ID. */
104
 
        if ((ret = __os_fileid(dbenv, real_name, 1, newmeta.dbmeta.uid)) != 0)
105
 
                return (ret);
106
 
 
107
 
        /* Overwrite the original. */
108
 
        memcpy(oldmeta, &newmeta, sizeof(newmeta));
109
 
 
110
 
        return (0);
111
 
}
112
 
 
113
 
/*
114
 
 * __ham_30_sizefix --
115
 
 *      Make sure that all hash pages belonging to the current
116
 
 *      hash doubling are within the bounds of the file.
117
 
 *
118
 
 * PUBLIC: int __ham_30_sizefix __P((DB *, DB_FH *, char *, u_int8_t *));
119
 
 */
120
 
int
121
 
__ham_30_sizefix(dbp, fhp, realname, metabuf)
122
 
        DB *dbp;
123
 
        DB_FH *fhp;
124
 
        char *realname;
125
 
        u_int8_t *metabuf;
126
 
{
127
 
        u_int8_t buf[DB_MAX_PGSIZE];
128
 
        DB_ENV *dbenv;
129
 
        HMETA30 *meta;
130
 
        db_pgno_t last_actual, last_desired;
131
 
        int ret;
132
 
        size_t nw;
133
 
        u_int32_t pagesize;
134
 
 
135
 
        dbenv = dbp->dbenv;
136
 
        memset(buf, 0, DB_MAX_PGSIZE);
137
 
 
138
 
        meta = (HMETA30 *)metabuf;
139
 
        pagesize = meta->dbmeta.pagesize;
140
 
 
141
 
        /*
142
 
         * Get the last page number.  To do this, we'll need dbp->pgsize
143
 
         * to be set right, so slam it into place.
144
 
         */
145
 
        dbp->pgsize = pagesize;
146
 
        if ((ret = __db_lastpgno(dbp, realname, fhp, &last_actual)) != 0)
147
 
                return (ret);
148
 
 
149
 
        /*
150
 
         * The last bucket in the doubling is equal to high_mask;  calculate
151
 
         * the page number that implies.
152
 
         */
153
 
        last_desired = BS_TO_PAGE(meta->high_mask, meta->spares);
154
 
 
155
 
        /*
156
 
         * If last_desired > last_actual, we need to grow the file.  Write
157
 
         * a zeroed page where last_desired would go.
158
 
         */
159
 
        if (last_desired > last_actual) {
160
 
                if ((ret = __os_seek(dbenv,
161
 
                    fhp, pagesize, last_desired, 0, 0, DB_OS_SEEK_SET)) != 0)
162
 
                        return (ret);
163
 
                if ((ret = __os_write(dbenv, fhp, buf, pagesize, &nw)) != 0)
164
 
                        return (ret);
165
 
        }
166
 
 
167
 
        return (0);
168
 
}
169
 
 
170
 
/*
171
 
 * __ham_31_hashmeta --
172
 
 *      Upgrade the database from version 6 to version 7.
173
 
 *
174
 
 * PUBLIC: int __ham_31_hashmeta
175
 
 * PUBLIC:      __P((DB *, char *, u_int32_t, DB_FH *, PAGE *, int *));
176
 
 */
177
 
int
178
 
__ham_31_hashmeta(dbp, real_name, flags, fhp, h, dirtyp)
179
 
        DB *dbp;
180
 
        char *real_name;
181
 
        u_int32_t flags;
182
 
        DB_FH *fhp;
183
 
        PAGE *h;
184
 
        int *dirtyp;
185
 
{
186
 
        HMETA31 *newmeta;
187
 
        HMETA30 *oldmeta;
188
 
 
189
 
        COMPQUIET(dbp, NULL);
190
 
        COMPQUIET(real_name, NULL);
191
 
        COMPQUIET(fhp, NULL);
192
 
 
193
 
        newmeta = (HMETA31 *)h;
194
 
        oldmeta = (HMETA30 *)h;
195
 
 
196
 
        /*
197
 
         * Copy the fields down the page.
198
 
         * The fields may overlap so start at the bottom and use memmove().
199
 
         */
200
 
        memmove(newmeta->spares, oldmeta->spares, sizeof(oldmeta->spares));
201
 
        newmeta->h_charkey = oldmeta->h_charkey;
202
 
        newmeta->nelem = oldmeta->nelem;
203
 
        newmeta->ffactor = oldmeta->ffactor;
204
 
        newmeta->low_mask = oldmeta->low_mask;
205
 
        newmeta->high_mask = oldmeta->high_mask;
206
 
        newmeta->max_bucket = oldmeta->max_bucket;
207
 
        memmove(newmeta->dbmeta.uid,
208
 
            oldmeta->dbmeta.uid, sizeof(oldmeta->dbmeta.uid));
209
 
        newmeta->dbmeta.flags = oldmeta->dbmeta.flags;
210
 
        newmeta->dbmeta.record_count = 0;
211
 
        newmeta->dbmeta.key_count = 0;
212
 
        ZERO_LSN(newmeta->dbmeta.unused3);
213
 
 
214
 
        /* Update the version. */
215
 
        newmeta->dbmeta.version = 7;
216
 
 
217
 
        /* Upgrade the flags. */
218
 
        if (LF_ISSET(DB_DUPSORT))
219
 
                F_SET(&newmeta->dbmeta, DB_HASH_DUPSORT);
220
 
 
221
 
        *dirtyp = 1;
222
 
        return (0);
223
 
}
224
 
 
225
 
/*
226
 
 * __ham_31_hash --
227
 
 *      Upgrade the database hash leaf pages.
228
 
 *
229
 
 * PUBLIC: int __ham_31_hash
230
 
 * PUBLIC:      __P((DB *, char *, u_int32_t, DB_FH *, PAGE *, int *));
231
 
 */
232
 
int
233
 
__ham_31_hash(dbp, real_name, flags, fhp, h, dirtyp)
234
 
        DB *dbp;
235
 
        char *real_name;
236
 
        u_int32_t flags;
237
 
        DB_FH *fhp;
238
 
        PAGE *h;
239
 
        int *dirtyp;
240
 
{
241
 
        HKEYDATA *hk;
242
 
        db_pgno_t pgno, tpgno;
243
 
        db_indx_t indx;
244
 
        int ret;
245
 
 
246
 
        COMPQUIET(flags, 0);
247
 
 
248
 
        ret = 0;
249
 
        for (indx = 0; indx < NUM_ENT(h); indx += 2) {
250
 
                hk = (HKEYDATA *)H_PAIRDATA(dbp, h, indx);
251
 
                if (HPAGE_PTYPE(hk) == H_OFFDUP) {
252
 
                        memcpy(&pgno, HOFFDUP_PGNO(hk), sizeof(db_pgno_t));
253
 
                        tpgno = pgno;
254
 
                        if ((ret = __db_31_offdup(dbp, real_name, fhp,
255
 
                            LF_ISSET(DB_DUPSORT) ? 1 : 0, &tpgno)) != 0)
256
 
                                break;
257
 
                        if (pgno != tpgno) {
258
 
                                *dirtyp = 1;
259
 
                                memcpy(HOFFDUP_PGNO(hk),
260
 
                                    &tpgno, sizeof(db_pgno_t));
261
 
                        }
262
 
                }
263
 
        }
264
 
 
265
 
        return (ret);
266
 
}