ref: 31e912ac95f8c315916cb9d6a8bc59026a6d28b2
parent: 876a3ee2195b4c22fea9d44ead9dc9966f07ddf3
author: Jacob Moody <moody@posixcafe.org>
date: Fri May 5 18:39:34 EDT 2023
ipsdiff refactor
--- a/ipsdiff.c
+++ b/ipsdiff.c
@@ -10,7 +10,7 @@
struct Bin{
int fd;
long dot;
- long n, off;
+ long n;
uchar data[0xFFFF];
};
@@ -20,13 +20,10 @@
static long
slurp(Bin *b)
{
- long n;
-
- n = readn(b->fd, b->data + b->off, sizeof b->data - b->off);
- if(n < 0)
+ b->n = readn(b->fd, b->data, sizeof b->data);
+ if(b->n < 0)
sysfatal("read: %r");
- b->n = b->off + n;
- return n;
+ return b->n;
}
static void
@@ -33,17 +30,35 @@
emit(u32int off, uchar *data, u16int size)
{
uchar buf[3 + 2];
+ uchar buf2[2 + 1];
+ uchar v, *p, *e;
if(size == 0)
return;
+
PUT3(buf, off);
+ if(size > 3 && data[0] == data[1]){
+ p = data + 2;
+ e = data + size;
+ v = data[0];
+ while(p < e && *p == v)
+ p++;
+ PUT2(buf2, size);
+ if(p == e)
+ size = 0;
+ buf2[2] = v;
+ }
+
PUT2(buf+3, size);
if(dump)
fprint(2, "%ud %ud\n", off, size);
if(Bwrite(ips, buf, sizeof buf) != sizeof buf)
sysfatal("Bwrite: %r");
- if(Bwrite(ips, data, size) != size)
+
+ if(size == 0 && Bwrite(ips, buf2, sizeof buf2) != sizeof buf2)
sysfatal("Bwrite: %r");
+ if(size != 0 && Bwrite(ips, data, size) != size)
+ sysfatal("Bwrite: %r");
}
static void
@@ -62,21 +77,22 @@
if(a->n != b->n)
sysfatal("desync: %ld %ld", a->n, a->n);
- while(ap < ae && bp < be){
+ for(; ap < ae && bp < be; ap = ac, bp = bc){
if(*ap == *bp){
- ap++;
- bp++;
+ ac = ap+1;
+ bc = bp+1;
continue;
}
- // FIXME: better way of expanding diff context
- x = 32;
+ x = 2;
for(ac = ap, bc = bp; ac < ae && bc < be; ac++, bc++){
- if(--x <= 0 && *ac == *bc)
+ if(*ac == *bc)
+ x--;
+ else
+ x = 2;
+ if(x == 0)
break;
}
emit(a->dot + (ap - a->data), bp, bc - bp);
- ap = ac;
- bp = bc;
}
a->dot += a->n;
b->dot += b->n;