...
|
...
|
@@ -43,6 +43,25 @@ static char sep_select(char *buf, int bufsize, char **pos);
|
43
|
43
|
static void *mymemrchr(const void *s, int c, size_t n);
|
44
|
44
|
static void meminvert(void *start, void *end);
|
45
|
45
|
|
|
46
|
+#if 0
|
|
47
|
+static void
|
|
48
|
+redata_debug_chunkdump(redata_t *redata, char *title)
|
|
49
|
+{
|
|
50
|
+ int m,k;
|
|
51
|
+ char c;
|
|
52
|
+ title=(title==NULL)?"":title;
|
|
53
|
+ fprintf(stderr,"%s:CHUNKDUMP (sizechunks:%i)\n",title,redata->sizechunks);
|
|
54
|
+ for(m=0;m<redata->sizechunks;m++) {
|
|
55
|
+ fprintf(stderr,"%s:chunk[%i]:\"",title,m);
|
|
56
|
+ for(k=0;k<redata->chunks[m]->useddata;k++) {
|
|
57
|
+ c=redata->chunks[m]->data[k];
|
|
58
|
+ c=(c>=' ' && c<='~')?c:'.';
|
|
59
|
+ fprintf(stderr,"%c",c);
|
|
60
|
+ }
|
|
61
|
+ fprintf(stderr,"\"\n");
|
|
62
|
+ }
|
|
63
|
+}
|
|
64
|
+#endif
|
46
|
65
|
|
47
|
66
|
redata_t *
|
48
|
67
|
redata_init(void)
|
...
|
...
|
@@ -534,6 +553,8 @@ redata_unsaved_trunc(redata_t *redata)
|
534
|
553
|
return(-1); /* malformed filename */
|
535
|
554
|
if(redata->unsavedfd!=-1)
|
536
|
555
|
close(redata->unsavedfd),redata->unsavedfd=-1;
|
|
556
|
+ redata_hash(redata,redata->initialhash);
|
|
557
|
+ redata->unsaved.usedbuf=0;
|
537
|
558
|
if((redata->unsavedfd=open(unsname,O_WRONLY|O_TRUNC|O_CREAT,0644))==-1)
|
538
|
559
|
return(-1); /* couldn't open file for writing */
|
539
|
560
|
if((n=write(redata->unsavedfd,header,sizeof(header)-1))==-1
|
...
|
...
|
@@ -879,12 +900,13 @@ redata_load(redata_t *redata, char *filename, int use_unsaved)
|
879
|
900
|
for(chunkno=0;chunkno<redata->sizechunks;chunkno++)
|
880
|
901
|
redata_whatin_refresh(redata,chunkno);
|
881
|
902
|
/* unsaved */
|
882
|
|
- redata_hash(redata,redata->initialhash);
|
883
|
903
|
if(use_unsaved) {
|
884
|
904
|
/* apply missing changes and append new changes to unsaved */
|
|
905
|
+ redata_hash(redata,redata->initialhash);
|
885
|
906
|
redata_unsaved_loadappend(redata);
|
886
|
907
|
} else {
|
887
|
908
|
/* nuke existing unsaved (if exists) and prepare new unsaved */
|
|
909
|
+ /* _trunc() fills itself redata->initialhash */
|
888
|
910
|
redata_unsaved_trunc(redata);
|
889
|
911
|
}
|
890
|
912
|
/* all done */
|
...
|
...
|
@@ -918,8 +940,9 @@ redata_save(redata_t *redata, char *filename)
|
918
|
940
|
return(-1); /* couldn't overwrite old file */
|
919
|
941
|
}
|
920
|
942
|
redata_unsaved_unlink(redata);
|
921
|
|
- redata_hash(redata,redata->initialhash);
|
922
|
|
- redata->unsaved.usedbuf=0;
|
|
943
|
+ strncpy(redata->filename,filename,sizeof(redata->filename));
|
|
944
|
+ redata->filename[sizeof(redata->filename)-1]='\0';
|
|
945
|
+ redata_unsaved_trunc(redata);
|
923
|
946
|
return(0);
|
924
|
947
|
}
|
925
|
948
|
|
...
|
...
|
@@ -1461,6 +1484,8 @@ redata_data_compare(redata_t *redata, long cmppos, char *buf, long buflen)
|
1461
|
1484
|
return(0);
|
1462
|
1485
|
}
|
1463
|
1486
|
|
|
1487
|
+
|
|
1488
|
+
|
1464
|
1489
|
int
|
1465
|
1490
|
redata_compact(redata_t *redata)
|
1466
|
1491
|
{
|
...
|
...
|
@@ -1468,8 +1493,44 @@ redata_compact(redata_t *redata)
|
1468
|
1493
|
/* criterion: */
|
1469
|
1494
|
/* 1. if two neighbouring chunks could join with 10% free in result chunk, do it */
|
1470
|
1495
|
/* 2. if there are more than 2 unused chunks free at the end, free all unused chunks except two */
|
1471
|
|
-#warning TODO
|
1472
|
|
- return(-1);
|
|
1496
|
+ int i,l;
|
|
1497
|
+ rechunk_t *chunk,**newchunks;
|
|
1498
|
+ if(redata==NULL)
|
|
1499
|
+ return(-1); /* sanity check failed */
|
|
1500
|
+ /* skip free chunks at end */
|
|
1501
|
+ for(i=redata->sizechunks-1;i>=0;i--) {
|
|
1502
|
+ if(redata->chunks[i]->useddata!=0)
|
|
1503
|
+ break;
|
|
1504
|
+ }
|
|
1505
|
+ /* join neighbouring chunks where appropiate */
|
|
1506
|
+ l=redata->chunkdatasize-(redata->chunkdatasize)/10;
|
|
1507
|
+ for(;i>0;i--) {
|
|
1508
|
+ if((redata->chunks[i]->useddata+redata->chunks[i-1]->useddata)>=l)
|
|
1509
|
+ continue;
|
|
1510
|
+ /* move data to prev. chunk, move chunk to end */
|
|
1511
|
+ redata_chunk_fillfromnext(redata,i-1,redata->chunks[i]->useddata);
|
|
1512
|
+ if(redata->chunks[i]->useddata>0)
|
|
1513
|
+ continue; /* couldn't move data */
|
|
1514
|
+ chunk=redata->chunks[i];
|
|
1515
|
+ memmove(redata->chunks+i,redata->chunks+i+1,sizeof(rechunk_t *)*(redata->sizechunks-i-1));
|
|
1516
|
+ redata->chunks[redata->sizechunks-1]=chunk;
|
|
1517
|
+ }
|
|
1518
|
+ /* free unused chunks at end (leave two empty chunks, free the rest) */
|
|
1519
|
+ for(i=redata->sizechunks-1;i>=0;i--) {
|
|
1520
|
+ if(redata->chunks[i]->useddata!=0)
|
|
1521
|
+ break;
|
|
1522
|
+ }
|
|
1523
|
+ l=i+3;
|
|
1524
|
+ if(l<redata->sizechunks) {
|
|
1525
|
+ for(i=l;i<redata->sizechunks;i++) {
|
|
1526
|
+ free(redata->chunks[i]),redata->chunks[i]=NULL;
|
|
1527
|
+ redata->available-=redata->chunkdatasize;
|
|
1528
|
+ }
|
|
1529
|
+ if((newchunks=realloc(redata->chunks,l*sizeof(rechunk_t *)))!=NULL)
|
|
1530
|
+ redata->chunks=newchunks;
|
|
1531
|
+ redata->sizechunks=l;
|
|
1532
|
+ }
|
|
1533
|
+ return(0);
|
1473
|
1534
|
}
|
1474
|
1535
|
|
1475
|
1536
|
int
|