output, so it's perfectly safe to cache it:
const char DB_PATH[]="./blogcache.txt";
unordered_map<ll, const char *> G_DB;
void loadDB() {
G_DB = {};
FILE *f = fopen(DB_PATH, "rb");
...
while (!feof(f)) {
ll k, len;
fread(&k, sizeof(ll), 1, f); if (feof(f)) break;
fread(&len, sizeof(ll), 1, f);
...
char *buf = (char *)calloc(sizeof(char), len + 2);
fread(buf, sizeof(char), len, f);
...
}
fclose(f);
};
const char *lookup_key(ll k) {
unordered_map<ll, const char *>::iterator it = G_DB.find(k);
if (it == G_DB.end()) { return nullptr; } return it->second;
};
void store_key_value(const ll k, KEEP const char *v, const ll len) {
assert(G_DB.count(k) == 0);
G_DB.insert(make_pair(k, strdup(v)));
FILE *f = fopen(DB_PATH, "ab");
assert(f != nullptr && "unable to open DB file");
fwrite(&k, sizeof(ll), 1, f);
fwrite(&len, sizeof(ll), 1, f);
fwrite(v, sizeof(char), len, f);
fclose(f);
}
§ For the future
I plan to rip out hevea
and write my own latex -> HTML
converter for
the subset of LaTeX I actually use . hevea
's strength is its downfall:
It can handle all of LaTeX, which means it's really slow. If I can concentrate
on a small subset, I don't need to play caching tricks, and I can likely
optimise the layout further for my use-cases.
I also want colored error messages, because who doesn't?
I'll probably gradually improve my static site generator over time. Once it's
at a level of polish where I'm happy with it, I'll spin it out as a separate
project.
§ Conclusions
Am I glad I did it? Yes, purely because my chunk of the internet aligns with
how I want it to be, and that makes me ϵ more happy.
I think of it as an investment into future me, since I can extend the
markdown and the transpiler in the way I want it to be.