~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to diff-delta.c

  • Committer: John Arbash Meinel
  • Date: 2009-03-03 16:31:07 UTC
  • mto: (0.17.31 trunk)
  • mto: This revision was merged to the branch mainline in revision 4280.
  • Revision ID: john@arbash-meinel.com-20090303163107-l4j0114btw2efmjp
Change the code around again.

This time, the information about sources is maintained in the DeltaIndex object.
And we pass that info down into create_delta_index, et al.

Next step is to actually combine the delta indexes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
112
112
        0x133eb0ac, 0x6d8b90a1, 0x450d4467, 0x3bb8646a
113
113
};
114
114
 
115
 
struct source_info {
116
 
        const void *src_buf; /* Pointer to the beginning of source data */
117
 
        unsigned long src_size; /* Total length of source data */
118
 
        unsigned long agg_src_offset; /* Start of source data as part of the
119
 
                                                                         aggregate source */
120
 
};
121
 
 
122
115
struct index_entry {
123
116
        const unsigned char *ptr;
124
117
        const struct source_info *src;
132
125
 
133
126
struct delta_index {
134
127
        unsigned long memsize; /* Total bytes pointed to by this index */
135
 
        struct source_info src; /* Information about the referenced source */
 
128
        struct source_info *src; /* Information about the referenced source */
136
129
        unsigned int hash_mask; /* val & hash_mask gives the hash index for a given
137
130
                                                           entry */
138
131
        unsigned int num_entries; /* The total number of entries in this index */
235
228
                 * into consecutive array entries.
236
229
                 */
237
230
                packed_hash[i] = packed_entry;
238
 
                for (entry = hash[i]; entry; entry = entry->next, ++packed_entry) {
239
 
                        *packed_entry = entry->entry;
240
 
                        packed_entry->src = &index->src;
241
 
                }
 
231
                for (entry = hash[i]; entry; entry = entry->next)
 
232
                        *packed_entry++ = entry->entry;
242
233
        }
243
234
 
244
235
        /* Sentinel value to indicate the length of the last hash bucket */
249
240
}
250
241
 
251
242
 
252
 
struct delta_index * create_delta_index(const void *buf, unsigned long bufsize,
253
 
                                                                                unsigned long agg_src_offset)
 
243
struct delta_index * create_delta_index(const struct source_info *src)
254
244
{
255
245
        unsigned int i, hsize, hmask, entries, prev_val, *hash_count;
256
 
        const unsigned char *data, *buffer = buf;
 
246
        const unsigned char *data, *buffer;
257
247
        struct delta_index *index;
258
248
        struct unpacked_index_entry *entry, **hash;
259
249
        void *mem;
260
250
        unsigned long memsize;
261
251
 
262
 
        if (!buf || !bufsize)
 
252
        if (!src->buf || !src->size)
263
253
                return NULL;
 
254
        buffer = src->buf;
264
255
 
265
256
        /* Determine index hash size.  Note that indexing skips the
266
257
           first byte to allow for optimizing the Rabin's polynomial
267
258
           initialization in create_delta(). */
268
 
        entries = (bufsize - 1)  / RABIN_WINDOW;
 
259
        entries = (src->size - 1)  / RABIN_WINDOW;
269
260
        hsize = entries / 4;
270
261
        for (i = 4; (1u << i) < hsize && i < 31; i++);
271
262
        hsize = 1 << i;
307
298
                        i = val & hmask;
308
299
                        entry->entry.ptr = data + RABIN_WINDOW;
309
300
                        entry->entry.val = val;
 
301
                        entry->entry.src = src;
310
302
                        entry->next = hash[i];
311
303
                        hash[i] = entry++;
312
304
                        hash_count[i]++;
316
308
        entries = limit_hash_buckets(hash, hash_count, hsize, entries);
317
309
        free(hash_count);
318
310
        index = pack_delta_index(hash, hsize, entries);
 
311
        index->src = src;
319
312
        free(hash);
320
313
        if (!index) {
321
314
                return NULL;
322
315
        }
323
 
        index->src.src_buf = buf;
324
 
        index->src.src_size = bufsize;
325
 
        index->src.agg_src_offset = agg_src_offset;
326
316
        return index;
327
317
}
328
318
 
376
366
        index = indexes[0];
377
367
        for (j = 0; j < num_indexes; ++j) {
378
368
                index = indexes[j];
379
 
                i += index->src.src_size;
 
369
                i += index->src->size;
380
370
        }
381
 
        assert(i <= index->src.src_size + index->src.agg_src_offset);
382
 
        i = index->src.src_size + index->src.agg_src_offset;
 
371
        assert(i <= index->src->size + index->src->agg_offset);
 
372
        i = index->src->size + index->src->agg_offset;
383
373
        while (i >= 0x80) {
384
374
                out[outpos++] = i | 0x80;
385
375
                i >>= 7;
441
431
                                                continue;
442
432
                                        ref = entry->ptr;
443
433
                                        src = data;
444
 
                                        ref_data = entry->src->src_buf;
445
 
                                        ref_top = ref_data + entry->src->src_size;
 
434
                                        ref_data = entry->src->buf;
 
435
                                        ref_top = ref_data + entry->src->size;
446
436
                                        ref_size = ref_top - ref;
447
437
                                        /* ref_size is the longest possible match that we could make
448
438
                                         * here. If ref_size <= msize, then we know that we cannot
490
480
                        unsigned char *op;
491
481
 
492
482
                        if (inscnt) {
493
 
                                ref_data = msource->src_buf;
 
483
                                ref_data = msource->buf;
494
484
                                while (moff && ref_data[moff-1] == data[-1]) {
495
485
                                        /* we can match one byte back */
496
486
                                        msize++;
517
507
                        /* moff is the offset in the local structure, for encoding, we need
518
508
                         * to push it into the global offset
519
509
                         */
520
 
                        moff += msource->agg_src_offset;
 
510
                        moff += msource->agg_offset;
521
511
                        if (moff & 0x000000ff)
522
512
                                out[outpos++] = moff >> 0,  i |= 0x01;
523
513
                        if (moff & 0x0000ff00)
529
519
                        /* Put it back into local coordinates, in case we have multiple
530
520
                         * copies in a row.
531
521
                         */
532
 
                        moff -= msource->agg_src_offset;
 
522
                        moff -= msource->agg_offset;
533
523
 
534
524
                        if (msize & 0x00ff)
535
525
                                out[outpos++] = msize >> 0, i |= 0x10;