Skip to content
This repository was archived by the owner on Jul 26, 2026. It is now read-only.

Commit 60f7768

Browse files
committed
Implemented everything about the merging of the bases into the topmost delta list. Its not yet working, but at least its not crashing
1 parent 166e538 commit 60f7768

1 file changed

Lines changed: 101 additions & 9 deletions

File tree

‎_fun.c‎

Lines changed: 101 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ typedef unsigned int uint;
9191
typedef unsigned char uchar;
9292
typedef uchar bool;
9393

94+
// Constants
95+
const ull gDVC_grow_by = 50;
96+
9497
// DELTA CHUNK
9598
////////////////
9699
// Internal Delta Chunk Objects
@@ -277,10 +280,17 @@ DeltaChunk* DCV_get(DeltaChunkVector* vec, Py_ssize_t i)
277280
return &vec->mem[i];
278281
}
279282

283+
// Return last item
284+
inline
285+
DeltaChunk* DCV_last(DeltaChunkVector* vec)
286+
{
287+
return DCV_get(vec, vec->size-1);
288+
}
289+
280290
inline
281291
ull DCV_rbound(DeltaChunkVector* vec)
282292
{
283-
return DC_rbound(DCV_get(vec, vec->size-1));
293+
return DC_rbound(DCV_last(vec));
284294
}
285295

286296
inline
@@ -371,14 +381,41 @@ static inline
371381
DeltaChunk* DCV_append(DeltaChunkVector* vec)
372382
{
373383
if (vec->size + 1 > vec->reserved_size){
374-
DCV_grow_by(vec, 1);
384+
DCV_grow_by(vec, gDVC_grow_by);
375385
}
376386

377387
DeltaChunk* next = vec->mem + vec->size;
378388
vec->size += 1;
379389
return next;
380390
}
381391

392+
// Return delta chunk being closest to the given absolute offset
393+
inline
394+
DeltaChunk* DCV_closest_chunk(DeltaChunkVector* vec, ull ofs)
395+
{
396+
assert(vec->mem);
397+
398+
ull lo = 0;
399+
ull hi = vec->size;
400+
ull mid;
401+
DeltaChunk* dc;
402+
403+
while (lo < hi)
404+
{
405+
mid = (lo + hi) / 2;
406+
dc = vec->mem + mid;
407+
if (dc->to > ofs){
408+
hi = mid;
409+
} else if ((DC_rbound(dc) > ofs) | (dc->to == ofs)) {
410+
return dc;
411+
} else {
412+
lo = mid + 1;
413+
}
414+
}
415+
416+
return DCV_last(vec);
417+
}
418+
382419
// Write a slice as defined by its absolute offset in bytes and its size into the given
383420
// destination. The individual chunks written will be a deep copy of the source
384421
// data chunks
@@ -387,14 +424,67 @@ DeltaChunk* DCV_append(DeltaChunkVector* vec)
387424
inline
388425
void DCV_copy_slice_to(DeltaChunkVector* src, DeltaChunkVector* dest, ull ofs, ull size)
389426
{
427+
assert(DCV_lbound(src) <= ofs);
428+
assert(DCV_rbound(src) <= ofs + size);
390429

430+
DeltaChunk* cdc = DCV_closest_chunk(src, ofs);
431+
432+
// partial overlap
433+
if (cdc->to != ofs) {
434+
DeltaChunk* destc = DCV_append(dest);
435+
const ull relofs = ofs - cdc->to;
436+
DC_offset_copy_to(cdc, destc, relofs, cdc->ts - relofs < size ? cdc->ts - relofs : size);
437+
cdc += 1;
438+
size -= destc->ts;
439+
440+
if (size == 0){
441+
return;
442+
}
443+
}
444+
445+
DeltaChunk* vecend = DCV_end(src);
446+
for( ;(cdc < vecend) && size; ++cdc)
447+
{
448+
if (cdc->ts < size) {
449+
DC_copy_to(cdc, DCV_append(dest));
450+
size -= cdc->ts;
451+
} else {
452+
DC_offset_copy_to(cdc, DCV_append(dest), 0, size);
453+
size = 0;
454+
break;
455+
}
456+
}
457+
458+
assert(size == 0);
391459
}
392460

393461

462+
// Insert all chunks in 'from' to 'to', starting at the delta chunk named 'at' which
463+
// originates in to
464+
// 'at' will be replaced by the items to insert ( special purpose )
465+
// 'at' will be properly destroyed, but all items will just be copied bytewise
466+
// using memcpy. Hence from must just forget about them !
467+
inline
468+
void DCV_replace_one_by_many(DeltaChunkVector* from, DeltaChunkVector* to, DeltaChunk* at)
469+
{
470+
assert(from->size > 1);
471+
472+
DCV_reserve_memory(to, to->size + from->size - 1); // -1 because we replace at
473+
DC_destroy(at);
474+
to->size -= 1 + from->size;
475+
476+
// If we are somewhere in the middle, we have to make some space
477+
if (DCV_last(to) != at) {
478+
memmove((void*)at+from->size, (void*)(at+1), (size_t)(DCV_end(to) - (at+1)));
479+
}
480+
481+
// Finally copy all the items in
482+
memcpy((void*) at, (void*)from->mem, from->size*sizeof(DeltaChunk));
483+
}
484+
394485
// Take slices of bdcv into the corresponding area of the tdcv, which is the topmost
395486
// delta to apply. tmpl is used as temporary space and must be initialzed and destroyed by the
396487
// caller
397-
static
398488
void DCV_connect_with_base(DeltaChunkVector* tdcv, DeltaChunkVector* bdcv, DeltaChunkVector* tmpl)
399489
{
400490
DeltaChunk* dc = tdcv->mem;
@@ -413,18 +503,20 @@ void DCV_connect_with_base(DeltaChunkVector* tdcv, DeltaChunkVector* bdcv, Delta
413503
// assert(tmpl->size);
414504

415505
// move target bounds
416-
DeltaChunk* cdc = tmpl->mem;
417-
DeltaChunk* cdcend = tmpl->mem + tmpl->size;
506+
DeltaChunk* tdc = tmpl->mem;
507+
DeltaChunk* tdcend = tmpl->mem + tmpl->size;
418508
const ull ofs = dc->to - dc->so;
419-
for(;cdc < cdcend; cdc++){
420-
cdc->to += ofs;
509+
for(;tdc < tdcend; tdc++){
510+
tdc->to += ofs;
421511
}
422512

423-
// insert slice into our list, replacing our current chunk
513+
// insert slice into our list
424514
if (tmpl->size == 1){
515+
// Its not data, so destroy is not really required, anyhow ...
516+
DC_destroy(dc);
425517
*dc = *DCV_get(tmpl, 0);
426518
} else {
427-
519+
DCV_replace_one_by_many(tmpl, tdcv, dc);
428520
}
429521

430522
// make sure the members will not be deallocated by the list

0 commit comments

Comments
 (0)