Ok, kap() is fixed. All the tests pass. Probably few more can
be enabled too. One remaining kap() difference from k3: k3
doesn't increment the refcount; kona does. In fact doing it
the k3 way will get rid of the cd() call made right after a
kap() call.
Will send out a push notification later today.
But first I should note a subtlety of kap() use. Originally
Neerav had code like this:
> K e11 = newK(-4,5); strcpy(kC(e11), "hello1"); kap(&r1, &e11);
> K e12 = newK(1,1) ; kI(e12)[0]=1 ; kap(&r2, &e12);
>
> // 2nd row
> K e21 = newK(-4,5); strcpy(kC(e21), "hello1"); kap(&r1, &e21);
> K e22 = newK(1,1) ; kI(e22)[0]=1 ; kap(&r2, &e22);
This won't work because kap() can potentially reallocate the
object. r1 or r2 will point to the new data but the
corresponding dictionary enty is still pointing to the old
object (which is gets recycled and may contain something else
or garbage). To fix this you can do one of two things: either
fix up the ptr later (How I update column 0 below) or pass the
appropriate ptr (column 1 below).
I i;
K d = gtn(5,0);
K c0 = gtn(0,0);
K c1 = gtn(-1,0);
K t0, t1, e;
t0 = gsk("a", c0); kap(&d,&t0);
t1 = gsk("b", c1); kap(&d,&t1);
e = gp("hello1"); kap(&c0,&e);
e = gp("hello2"); kap(&c0,&e);
KK(KK(d)[0])[1] = c0;
i = 1; kap(&KK(KK(d)[1])[1], &i);
i = 2; kap(&KK(KK(d)[1])[1], &i);
But kap will generally be slower. If you know the size
upfront, preallocate that much data and manually set things.
K c0 = gtn(0,2);
K c1 = gtn(-1,2);
KK(c0)[0] = gp("hello1"); KI(c1)[0] = 1;
KK(c0)[1] = gp("hello2"); KI(c1)[1] = 2;
K d = gtn(5,2);
KK(d)[0] = gsk("a", c0);
KK(d)[1] = gsk("b", c0);
When you are reading lots and lots of rows, kap() calls can be
expensive. An alternative is to buffer up a few locally and
then call kapn() on n entries. Will require adding kapn to the
API.