ref: 4b6deb085f97251e0d57936db726b0f9fd8c5512
parent: 8a0a5128be9870261845756ad9b924a613829f7b
author: Ori Bernstein <ori@eigenstate.org>
date: Fri Apr 7 12:48:47 EDT 2023
log: compress it live
--- a/blk.c
+++ b/blk.c
@@ -290,6 +290,7 @@
dropblk(pb);
}
*tl = lb;
+ a->nlog++;
}
if(len == Blksz){
@@ -538,6 +539,9 @@
unlock(a);
}
}
+ lock(a);
+ a->nlog = 0;
+ unlock(a);
finalize(a->tail);
if(syncblk(a->tail) == -1)
return -1;
--- a/dat.h
+++ b/dat.h
@@ -514,9 +514,10 @@
vlong size;
vlong used;
vlong reserve;
- /* freelist */
- Bptr head;
- Blk *tail; /* tail held open for writing */
+ /* allocation log */
+ vlong nlog; /* number of blocks logged since last compression */
+ Bptr head; /* start of allocation log */
+ Blk *tail; /* end of the log, open for writing */
Syncq *sync;
};
--- a/fs.c
+++ b/fs.c
@@ -2125,6 +2125,7 @@
void
runtasks(int, void *)
{
+ int i, c;
Fmsg *m;
Amsg *a;
@@ -2142,6 +2143,25 @@
a->halt = 0;
a->fd = -1;
m->a = a;
- chsend(fs->wrchan, m);
+ chsend(fs->wrchan, m);
+
+ /*
+ * compresslog is designed to be concurrent with allocation,
+ * so it's safe to call from outside the mutator proc; we
+ * don't want to spend a ton of time compressing, though,
+ * so we only do the compression when our log gets big.
+ *
+ * 1/4 of our reserved emergency space seems like a good
+ * heuristic for big, but it was picked arbitrarily.
+ */
+ for(i = 0; i < fs->narena; i++){
+ lock(&fs->arenas[i]);
+ c = fs->arenas[i].nlog > fs->arenas[i].reserve/(4*Blksz);
+ unlock(&fs->arenas[i]);
+ if(c){
+ if(compresslog(&fs->arenas[i]) == -1)
+ fprint(2, "compress log: %r");
+ }
+ }
}
}