changestore: load changes on demand

laumann
Jul 20, 2023, 8:19 PM
QSQNGA5KZ4BVWE4FUJUMOP6SJRIXAC2PYU6JSRG5KXWLYWZZMAJQC

Dependencies

  • [2] EHVLRMEF change: add vertexeq, fix deleted lines duplication
  • [3] P5CSMRVS change: fix sequence-point warning
  • [4] RRYWNHFE change: pass verbose to print_atom()
  • [5] PC54CREY hunk: free hunk list resources properly
  • [6] CWII6DAS change: free entries in changestorefree()
  • [7] UM5XFLGI change: add and call authorsfree()
  • [8] YDQLW2ZO change: rework printing of patches - print Edit and Newvertex types
  • [9] N3PUHKQN change: fix scoping issue
  • [10] TGT4VSME change: decode FILE_ADD
  • [11] QLH63JBH change: replace calls to abort() with die()
  • [12] NEORNIZE change: decode and print file moves
  • [13] 5D2IYPL7 change: introduce changestore, print deleted lines
  • [14] 7WA2F6RS change: decode resurrectzombies, addroot, delroot
  • [15] JVU3TTT5 all: switch away from typedefing anonymous structs
  • [16] 33ZXTRXR change: decode and print file deletions
  • [17] XTVLIC24 change: refactor to print_change()
  • [18] Q7TKZCJP Add initial support for reading the offsets from a (fixed) change
  • [*] Y26WT3ZF change: decode message, description and timestamp
  • [*] YFBKBUKB change: rename binstat -> bc
  • [*] LVX6U4EK change: decode metadata bytes

Change contents

  • edit in change.h at line 106
    [8.1363]
    [8.1363]
    char *repodir; /* absolute path to the changestore */
  • replacement in change.h at line 112
    [8.1423][8.1423:1479]()
    void changestoreinit(struct changestore *, size_t cap);
    [8.1423]
    [8.1479]
    void changestoreinit(struct changestore *, size_t cap, const char *);
  • edit in change.h at line 120
    [8.1690]
    [8.1005]
    int changestoreload(struct changestore *, struct hash *);
  • edit in change.c at line 454
    [20.1130]
    [21.5467]
    hashed->header.description = NULL;
  • edit in change.c at line 499
    [21.6005]
    [22.60]
    hashed->metadata = NULL;
  • edit in change.c at line 574
    [2.594]
    [8.3153]
    if (!ch) {
    changestoreload(changes, &vto->change);
    ch = changestoreget(changes, &vto->change);
    }
  • replacement in change.c at line 692
    [8.635][4.690:745]()
    print_positionlist(&v->downcontext);
    printf("\n");
    [8.635]
    [8.690]
    /* print_positionlist(&v->downcontext); */
    /* printf("\n"); */
  • edit in change.c at line 903
    [8.1849][8.1849:1853](),[8.1853][8.5529:5967](),[8.5991][8.5991:6077](),[8.6077][7.38:67](),[7.67][8.6117:6184](),[8.6117][8.6117:6184](),[8.1853][8.992:995](),[8.6184][8.992:995](),[8.992][8.992:995](),[8.995][6.0:19](),[6.19][8.6185:6193](),[8.995][8.6185:6193](),[8.6193][7.68:319]()
    }
    }
    }
    struct change *
    changestoreget(struct changestore *store, struct hash *hash)
    {
    size_t i;
    for (i = 0; i < store->len; i++) {
    if (hasheq(hash, &store->entries[i].hash))
    return &store->entries[i].change;
    }
    return NULL;
    }
    void
    changestoreinit(struct changestore *s, size_t cap)
    {
    s->entries = xmalloc(sizeof(struct changeentry) * cap);
    s->cap = cap;
    s->len = 0;
    }
    void
    changestorefree(struct changestore *s)
    {
    size_t i;
    struct change *c;
    /* Free all the entries first */
    for (i = 0; i < s->len; i++) {
    c = &s->entries[i].change;
    hashedfree(&c->hashed);
    if (c->contents)
    free(c->contents);
    }
    free(s->entries);
    }
    void
    authorsfree(struct authors *authors)
    {
    size_t i, j;
    struct author *author;
    for (i = 0; i < authors->len; i++) {
    author = &authors->map[i];
    for (j = 0; j < author->len; j++) {
    free(author->entries[j].key);
    free(author->entries[j].value);
  • edit in change.c at line 904
    [7.323][7.323:348]()
    free(author->entries);
  • edit in change.c at line 905
    [7.351][7.351:372]()
    free(authors->map);
  • edit in change.c at line 907
    [7.375][7.375:380](),[7.380][8.6193:6224](),[8.6193][8.6193:6224](),[8.6224][7.381:529](),[7.529][8.6224:6329](),[8.6224][8.6224:6329](),[8.6329][5.2198:2224](),[5.2224][8.995:997](),[8.6329][8.995:997](),[8.995][8.995:997](),[8.997][8.1854:1855]()
    void
    hashedfree(struct hashed *h)
    {
    free(h->header.message);
    if (h->header.description)
    free(h->header.description);
    free(h->header.timestamp);
    authorsfree(&h->header.authors);
    hashlist_free(&h->dependencies);
    hashlist_free(&h->extraknown);
    if (h->metadata)
    free(h->metadata);
    hunklistfree(&h->hunks);
    }
  • edit in change.c at line 1015
    [8.8048]
    [8.8048]
    }
    struct change *
    changestoreget(struct changestore *store, struct hash *hash)
    {
    size_t i;
    for (i = 0; i < store->len; i++) {
    if (hasheq(hash, &store->entries[i].hash))
    return &store->entries[i].change;
    }
    return NULL;
    }
    // loading changes as needed: ==15877== total heap usage: 326 allocs, 326 frees, 50,066,715 bytes allocated
    /**
    * load a change by the given hash into the changestore
    */
    int
    changestoreload(struct changestore *store, struct hash *hash)
    {
    struct changeentry *ch;
    size_t i;
    int err;
    if (store->len == store->cap) {
    /* resize */
    size_t newcap = store->cap << 1;
    store->entries = xrealloc(
    store->entries, sizeof(struct changeentry) * newcap
    );
    store->cap = newcap;
    }
    i = store->len;
    ch = &store->entries[i];
    err = loadchangeh(&ch->change, &ch->hash, store->repodir, hash, 0);
    if (err)
    return err;
    store->len++;
    return err;
    }
    void
    changestoreinit(struct changestore *s, size_t cap, const char *repodir)
    {
    s->repodir = xstrdup(repodir);
    s->entries = xmalloc(sizeof(struct changeentry) * cap);
    s->cap = cap;
    s->len = 0;
    }
    void
    changestorefree(struct changestore *s)
    {
    size_t i;
    struct change *c;
    /* Free all the entries first */
    for (i = 0; i < s->len; i++) {
    c = &s->entries[i].change;
    hashedfree(&c->hashed);
    if (c->contents)
    free(c->contents);
    }
    free(s->repodir);
    free(s->entries);
    }
    void
    authorsfree(struct authors *authors)
    {
    size_t i, j;
    struct author *author;
    for (i = 0; i < authors->len; i++) {
    author = &authors->map[i];
    for (j = 0; j < author->len; j++) {
    free(author->entries[j].key);
    free(author->entries[j].value);
    }
    free(author->entries);
    }
    free(authors->map);
  • edit in change.c at line 1103
    [8.8051]
    [8.8051]
    void
    hashedfree(struct hashed *h)
    {
    free(h->header.message);
    if (h->header.description)
    free(h->header.description);
    free(h->header.timestamp);
    authorsfree(&h->header.authors);
    hashlist_free(&h->dependencies);
    hashlist_free(&h->extraknown);
    if (h->metadata)
    free(h->metadata);
    hunklistfree(&h->hunks);
    }
  • replacement in change.c at line 1130
    [8.8293][8.8293:8329]()
    changestoreinit(&changestore, 32);
    [8.8293]
    [8.8329]
    changestoreinit(&changestore, 4, repodir);
  • edit in change.c at line 1139
    [8.8516][8.8516:8517](),[8.8517][8.8517:8786](),[8.8786][3.27:72](),[3.72][8.8822:9090](),[8.8822][8.8822:9090](),[8.9090][3.73:118](),[3.118][8.9126:9129](),[8.9126][8.9126:9129]()
    for (i = 0; i < ch->change.hashed.dependencies.len; i++) {
    err = loadchangeh(
    &changestore.entries[x].change,
    &changestore.entries[x].hash, repodir,
    &ch->change.hashed.dependencies.entries[i], verbose
    );
    if (err)
    goto changeout;
    changestore.len++;
    changestore.entries[x].num = x + 1;
    x++;
    }
    for (i = 0; i < ch->change.hashed.extraknown.len; i++) {
    err = loadchangeh(
    &changestore.entries[x].change,
    &changestore.entries[x].hash, repodir,
    &ch->change.hashed.extraknown.entries[i], verbose
    );
    if (err)
    goto changeout;
    changestore.len++;
    changestore.entries[x].num = x + 1;
    x++;
    }