static void xswap(lasvm_kcache_t *self, int i1, int i2, int r1, int r2) { int k = self->rnext[-1]; while (k >= 0) { int nk = self->rnext[k]; int n = self->rsize[k]; int rr = self->i2r[k]; float *d = self->rdata[k]; if (r1 < n) { if (r2 < n) { float t1 = d[r1]; float t2 = d[r2]; d[r1] = t2; d[r2] = t1; } else if (rr == r2) { d[r1] = self->rdiag[k]; } else { int arsize = self->rsize[i2]; if (rr < arsize && rr != r1) d[r1] = self->rdata[i2][rr]; else xtruncate(self, k, r1); } } else if (r2 < n) { if (rr == r1) { d[r2] = self->rdiag[k]; } else { int arsize = self->rsize[i1]; if (rr < arsize && rr != r2) d[r2] = self->rdata[i1][rr]; else xtruncate(self, k, r2); } } k = nk; } self->r2i[r1] = i2; self->r2i[r2] = i1; self->i2r[i1] = r2; self->i2r[i2] = r1; }
static void xpurge(lasvm_kcache_t *self) { if (self->cursize>self->maxsize) { int k = self->rprev[-1]; while (self->cursize>self->maxsize && k!=self->rnext[-1]) { int pk = self->rprev[k]; xtruncate(self, k, 0); k = pk; } } }
int lasvm_kcache_shuffle(lasvm_kcache_t *self, int *ilist, int ilen) { int k = 0; int maxid = 0; float *m = 0; char *c = 0; int mrl = 0; int i, j, r; ASSERT(ilist); ASSERT(ilen>0); /* find max index */ for (r=0; r<ilen; r++) { i = ilist[r]; ASSERT(i>=0 && i<self->l); maxid = max(maxid, i); } /* compute map */ xminsize(self, maxid+1); c = xmalloc(self->l); memset(c, 0, self->l * sizeof(char)); for (r=0; r<ilen; r++) c[ ilist[r] ] = 1; /* sort ilist and remove duplicates */ ilen = 0; for (i=0; i<self->l; i++) if (c[i]) ilist[ilen++] = i; /* reorganize cache entries */ m = xmalloc(ilen * sizeof(float)); k = self->rnext[-1]; while (k >= 0) { int nk = self->rnext[k]; int n = self->rsize[k]; int rr = self->i2r[k]; float *d = self->rdata[k]; /* collect */ for (j=0; j<ilen; j++) { int r = self->i2r[ ilist[j] ]; if (r < n) m[j] = d[r]; else if (r == rr) m[j] = self->rdiag[r]; else break; } /* copy */ if (j < n) xtruncate(self, k, j); else xextend(self, k, j); d = self->rdata[k]; for (i=0; i<j; i++) d[i] = m[i]; mrl = max(mrl, j); /* next */ k = nk; } free(m); /* recompose i2r and r2i */ r = 0; for (i=0; i<self->l; i++) if (c[i]) self->r2i[r++] = i; for (i=0; i<self->l; i++) if (!c[i]) self->r2i[r++] = i; ASSERT(r == self->l); for (r=0; r<self->l; r++) self->i2r[ self->r2i[r] ] = r; ASSERT(mrl <= ilen); free(c); /* return */ self->maxrowlen = mrl; return ilen; }
static void xswap(lasvm_kcache_t *self, int i1, int i2, int r1, int r2) { /* swap row data */ if (r1 < self->maxrowlen || r2 < self->maxrowlen ) { int mrl = 0; int k = self->rnext[-1]; while (k >= 0) { int nk = self->rnext[k]; int n = self->rsize[k]; int rr = self->i2r[k]; float *d = self->rdata[k]; if (r1 < n) { if (r2 < n) { float t1 = d[r1]; float t2 = d[r2]; d[r1] = t2; d[r2] = t1; } else if (rr == r2) { d[r1] = self->rdiag[k]; } else { int arsize = self->rsize[i2]; if (rr < arsize && rr != r1) d[r1] = self->rdata[i2][rr]; else xtruncate(self, k, r1); } } else if (r2 < n) { if (rr == r1) { d[r2] = self->rdiag[k]; } else { int arsize = self->rsize[i1]; if (rr < arsize && rr != r2) d[r2] = self->rdata[i1][rr]; else xtruncate(self, k, r2); } } mrl = max(mrl, self->rsize[k]); k = nk; } self->maxrowlen = mrl; } /* swap r2i and i2r */ self->r2i[r1] = i2; self->r2i[r2] = i1; self->i2r[i1] = r2; self->i2r[i2] = r1; }