Пример #1
0
static void recurse_print(fs_ptree *pt, nodeid n, char *buffer, int pos, struct ptree_stats *stats, FILE *out, int verbosity)
{
    unsigned int len = 0;
    node *no = node_ref(pt, n);
    int branches = 0;
    int leaves = 0;
    for (int b=0; b<FS_PTREE_BRANCHES; b++) {
        sprintf(buffer+pos, "%x", b);
        if (no->branch[b] == FS_PTREE_NULL_NODE) {
            (stats->deadends)++;
        } else if (IS_LEAF(no->branch[b])) {
            branches++;
            leaves++;
            (stats->leaves)++;
            buffer[pos+1] ='\0';
            fprintf(out, "%-32s [B%08x, %016llx x %d]\n", buffer,
                    LEAF_REF(pt, no->branch[b])->block,
                    LEAF_REF(pt, no->branch[b])->pk,
                    LEAF_REF(pt, no->branch[b])->length);
            if (pt->table) {
                int check_len = 0;
                fs_ptable_check_consistency(pt->table, out, no->branch[b], LEAF_REF(pt, no->branch[b])->block, &check_len);
                if (LEAF_REF(pt, no->branch[b])->length != check_len) {
                    fprintf(out, "ERROR: tree leaf has length %d, but consistency check says %d\n", LEAF_REF(pt, no->branch[b])->length, check_len);
                }
                if (LEAF_REF(pt, no->branch[b])->length == 0) {
                    if (LEAF_REF(pt, no->branch[b])->block != 0) {
                        fprintf(out, "ERROR: tree leaf has 0 length, but block is non-zero\n");
                    } else {
                        fprintf(out, "ERROR: tree leaf has 0 length, should have been colected\n");
                    }
                } else if (LEAF_REF(pt, no->branch[b])->length < 0) {
                    fprintf(out, "ERROR: tree node length is %d\n", LEAF_REF(pt, no->branch[b])->length < 0);
                } else if (LEAF_REF(pt, no->branch[b])->block == 0) {
                    fprintf(out, "ERROR: tree node references block zero, but has non-zero length\n");
                } else if ((len = fs_ptable_chain_length(pt->table, LEAF_REF(pt, no->branch[b])->block, LEAF_REF(pt, no->branch[b])->length + 100)) != LEAF_REF(pt, no->branch[b])->length) {
                    if (LEAF_REF(pt, no->branch[b])->length + 101 == len) {
                        fprintf(out, "ERROR: probable loop in table, tree node length %d, table length > %d\n",
                            LEAF_REF(pt, no->branch[b])->length,
                            len);
                    } else {
                        fprintf(out, "ERROR: tree node length %d != table length %d\n",
                            LEAF_REF(pt, no->branch[b])->length,
                            len);
                    }
                }
            }
            stats->count += LEAF_REF(pt, no->branch[b])->length;
            for (int c=0; c<pos; c++) {
                buffer[c] = '.';
            }
        } else {
            (stats->nodes)++;
            branches++;
            recurse_print(pt, no->branch[b], buffer, pos+1, stats, out, verbosity);
        }
    }
    if (branches == 1 && leaves == 1 && pos > 2 && n != FS_PTREE_ROOT_NODE) {
        fprintf(out, "ERROR: node %08x has 1 leaf at depth %d, should have "
                     "been merged up\n", n, pos);
    } else if (branches == 0 && n != FS_PTREE_ROOT_NODE) {
        fprintf(out, "ERROR: node %08x has 0 branches at depth %d, should "
                     "have been culled\n", n, pos);
    }
}
Пример #2
0
fs_row_id fs_ptable_remove_pair(fs_ptable *pt, fs_row_id b, fs_rid pair[2], int *removed)
{
    fs_row_id ret = b;

    if (b == 0) {
        fs_error(LOG_CRIT, "tried to read row 0");

        return ret;
    }
    if (b > pt->header->length) {
        fs_error(LOG_CRIT, "tried to read off end of ptable (%d > %d)", b, pt->header->length);

        return ret;
    }

    /* NULL, NULL means remove everything */
    if (pair[0] == FS_RID_NULL && pair[1] == FS_RID_NULL) {
        *removed += fs_ptable_chain_length(pt, b, 0);
        fs_ptable_remove_chain(pt, b);

        return 0;
    }

    row *prevr = NULL;
    while (b != 0) {
        row *r = &(pt->data[b]);
        fs_row_id nextb = r->cont;
        if (pair[0] != FS_RID_NULL && pair[1] == FS_RID_NULL) {
            if (r->data[0] == pair[0]) {
                if (prevr) {
                    prevr->cont = nextb;
                } else {
                    ret = nextb;
                }
                fs_ptable_free_row(pt, b);
                (*removed)++;
            } else {
                prevr = r;
            }
        } else if (pair[0] == FS_RID_NULL && pair[1] != FS_RID_NULL) {
            if (r->data[1] == pair[1]) {
                if (prevr) {
                    prevr->cont = nextb;
                } else {
                    ret = nextb;
                }
                fs_ptable_free_row(pt, b);
                (*removed)++;
            } else {
                prevr = r;
            }
        } else if (pair[0] != FS_RID_NULL && pair[1] != FS_RID_NULL) {
            if (r->data[0] == pair[0] && r->data[1] == pair[1]) {
                if (prevr) {
                    prevr->cont = nextb;
                } else {
                    ret = nextb;
                }
                fs_ptable_free_row(pt, b);
                (*removed)++;
            } else {
                prevr = r;
            }
        } else {
            fs_error(LOG_CRIT, "trying to remove with unsupported pattern");
        }
        b = nextb;
    }

    return ret;
}