Working through 3-leb range deletes, proving to be problematic

The seperate interactions between ids and keys is new and confusing.
This was something that the previous combined weights hid.
This commit is contained in:
Christopher Haster
2023-01-26 10:35:13 -06:00
parent 5e0418029d
commit 588a103db7
3 changed files with 1990 additions and 1718 deletions
+197 -92
View File
@@ -457,13 +457,15 @@ enum lfsr_tag_type {
LFSR_TAG_MKBRANCH = 0x0400, LFSR_TAG_MKBRANCH = 0x0400,
LFSR_TAG_MKREG = 0x0410, LFSR_TAG_MKREG = 0x0410,
LFSR_TAG_MKDIR = 0x0420, LFSR_TAG_MKDIR = 0x0420,
LFSR_TAG_RM = 0x0402,
LFSR_TAG_UATTR = 0x2000, LFSR_TAG_UATTR = 0x2000,
LFSR_TAG_RMUATTR = 0x2001, LFSR_TAG_RMUATTR = 0x2002,
LFSR_TAG_BTREE = 0x0820, LFSR_TAG_BTREE = 0x0820,
LFSR_TAG_EXPAND = 0x0004, // TODO these
LFSR_TAG_SHRINK = 0x0014, // LFSR_TAG_EXPAND = 0x0004,
// LFSR_TAG_SHRINK = 0x0014,
LFSR_TAG_ALT = 0x0008, LFSR_TAG_ALT = 0x0008,
LFSR_TAG_ALTBLE = 0x0008, LFSR_TAG_ALTBLE = 0x0008,
@@ -491,6 +493,10 @@ enum lfsr_tag_type {
(LFSR_TAG_UATTR \ (LFSR_TAG_UATTR \
| ((0xff & (lfsr_tag_t)(attr)) << 4)) | ((0xff & (lfsr_tag_t)(attr)) << 4))
#define LFSR_TAG_RMUATTR(attr) \
(LFSR_TAG_RMUATTR \
| ((0xff & (lfsr_tag_t)(attr)) << 4))
//#define LFSR_ALT_(color, dir, weight) //#define LFSR_ALT_(color, dir, weight)
// (LFSR_TAG_ALT // (LFSR_TAG_ALT
// | ((0x1 & (lfsr_tag_t)(color)) << 0) // | ((0x1 & (lfsr_tag_t)(color)) << 0)
@@ -779,7 +785,7 @@ static inline lfsr_tag_t lfsr_tag_flipalt(lfsr_tag_t alt) {
return alt ^ 0x4; return alt ^ 0x4;
} }
static inline lfs_size_t lfsr_tag_flipweight(lfsr_tag_t alt, lfs_size_t weight, static inline lfs_size_t lfsr_tag_flipweight(lfs_size_t weight,
lfsr_sid_t lower, lfsr_sid_t upper) { lfsr_sid_t lower, lfsr_sid_t upper) {
return (upper-lower) - weight - 1; return (upper-lower) - weight - 1;
} }
@@ -810,11 +816,11 @@ static inline void lfsr_tag_trimtag(lfsr_tag_t alt,
// TODO test if we fit id??? // TODO test if we fit id???
if (lfsr_tag_isgt(alt)) { if (lfsr_tag_isgt(alt)) {
if (id == upper_id-1) { if (id == upper_id-1) {
*upper_tag = alt; *upper_tag = alt + 0x10;
} }
} else { } else {
if (id == lower_id) { if (id == lower_id) {
*lower_tag = alt; *lower_tag = alt + 0x10;
} }
} }
//} //}
@@ -1458,34 +1464,42 @@ static int lfsr_rbyd_fetch(lfs_t *lfs, lfsr_rbyd_t *rbyd,
// on a bad crc // on a bad crc
weight += 1; weight += 1;
// found an expand/shrink? update id count } else if (tag == LFSR_TAG_RM) {
} else if (tag == LFSR_TAG_EXPAND || tag == LFSR_TAG_SHRINK) {
uint8_t buf[5];
err = lfs_bd_read(lfs,
NULL, &lfs->rcache, limit-off,
block, off, buf, lfs_min(size, 5));
if (err) {
if (err == LFS_ERR_CORRUPT) {
break;
}
return err;
}
lfs_size_t weight_;
lfs_ssize_t delta = lfs_fromleb128(&weight_, buf, 5);
if (delta < 0) {
return delta;
}
// NOTE we can't check for overflow/underflow here because we // NOTE we can't check for overflow/underflow here because we
// may be overeagerly parsing an invalid commit, it's ok for // may be overeagerly parsing an invalid commit, it's ok for
// this to overflow/underflow as long as we throw it out later // this to overflow/underflow as long as we throw it out later
// on a bad crc // on a bad crc
if (tag == LFSR_TAG_EXPAND) { weight -= 1;
weight += weight_;
} else { // TODO this
weight -= weight_; // // found an expand/shrink? update id count
} // } else if (tag == LFSR_TAG_EXPAND || tag == LFSR_TAG_SHRINK) {
// uint8_t buf[5];
// err = lfs_bd_read(lfs,
// NULL, &lfs->rcache, limit-off,
// block, off, buf, lfs_min(size, 5));
// if (err) {
// if (err == LFS_ERR_CORRUPT) {
// break;
// }
// return err;
// }
//
// lfs_size_t weight_;
// lfs_ssize_t delta = lfs_fromleb128(&weight_, buf, 5);
// if (delta < 0) {
// return delta;
// }
//
// // NOTE we can't check for overflow/underflow here because we
// // may be overeagerly parsing an invalid commit, it's ok for
// // this to overflow/underflow as long as we throw it out later
// // on a bad crc
// if (tag == LFSR_TAG_EXPAND) {
// weight += weight_;
// } else {
// weight -= weight_;
// }
// found an fcrc? save for later // found an fcrc? save for later
} else if (tag == LFSR_TAG_FCRC) { } else if (tag == LFSR_TAG_FCRC) {
@@ -1666,7 +1680,7 @@ static int lfsr_rbyd_lookup(lfs_t *lfs, const lfsr_rbyd_t *rbyd,
// TODO trimflipped? // TODO trimflipped?
lfsr_tag_trimweight( lfsr_tag_trimweight(
lfsr_tag_flipalt(alt), lfsr_tag_flipalt(alt),
lfsr_tag_flipweight(alt, weight_, lower, upper), lfsr_tag_flipweight(weight_, lower, upper),
&lower, &upper); &lower, &upper);
branch = branch - jump; branch = branch - jump;
} else { } else {
@@ -1942,12 +1956,43 @@ static int lfsr_rbyd_append(lfs_t *lfs, lfsr_rbyd_t *rbyd_,
lfsr_tag_t tag, lfsr_sid_t id, const void *buffer, lfs_size_t size) { lfsr_tag_t tag, lfsr_sid_t id, const void *buffer, lfs_size_t size) {
// tags must be in a valid id range at this point // tags must be in a valid id range at this point
if (lfsr_tag_ismk(tag)) { if (lfsr_tag_ismk(tag)) {
LFS_ASSERT(rbyd_->weight < 0xffff);
LFS_ASSERT(id <= rbyd_->weight);
} else { } else {
LFS_ASSERT(id < rbyd_->weight); LFS_ASSERT(id < rbyd_->weight);
} }
// figure out the range of tags to replace
lfsr_tag_t lower_tag_;
lfsr_sid_t lower_id_;
lfsr_tag_t upper_tag_;
lfsr_sid_t upper_id_;
if (lfsr_tag_ismk(tag)) {
LFS_ASSERT(rbyd_->weight < 0xffff);
LFS_ASSERT(id <= rbyd_->weight);
lower_tag_ = 0;
lower_id_ = id;
upper_tag_ = lower_tag_;
upper_id_ = lower_id_;
} else if (tag == LFSR_TAG_RM) {
LFS_ASSERT(rbyd_->weight > 0);
LFS_ASSERT(id < rbyd_->weight);
lower_tag_ = 0;
lower_id_ = id;
upper_tag_ = 0;
upper_id_ = lower_id_ + 1;
} else if (lfsr_tag_isrm(tag)) {
LFS_ASSERT(id < rbyd_->weight);
lower_tag_ = tag & ~0x2;
lower_id_ = id;
upper_tag_ = lower_tag_ + 0x10;
upper_id_ = lower_id_;
} else {
LFS_ASSERT(id < rbyd_->weight);
lower_tag_ = tag;
lower_id_ = id;
upper_tag_ = lower_tag_;
upper_id_ = lower_id_;
}
// assume we'll update our trunk // assume we'll update our trunk
lfs_off_t lower_branch = rbyd_->trunk; lfs_off_t lower_branch = rbyd_->trunk;
lfs_off_t upper_branch = lower_branch; lfs_off_t upper_branch = lower_branch;
@@ -1958,32 +2003,6 @@ static int lfsr_rbyd_append(lfs_t *lfs, lfsr_rbyd_t *rbyd_,
goto leaf; goto leaf;
} }
// figure out the range of tags to replace
lfsr_tag_t lower_tag_;
lfsr_sid_t lower_id_;
lfsr_tag_t upper_tag_;
lfsr_sid_t upper_id_;
if (lfsr_tag_ismk(tag)) {
lower_tag_ = 0;
lower_id_ = id;
upper_tag_ = lower_tag_;
upper_id_ = lower_id_;
// } else if (lfsr_tag_suptype(tag) == LFSR_TAG_RM) {
// LFS_ASSERT(rbyd_->count > 0);
// lower_tag_ = tag & ~0x7fff;
// upper_tag_ = lower_tag_ + 0x8000;
// } else if (lfsr_tag_isrm(tag)) {
// lower_tag_ = tag & ~0x2;
// lower_id_ = id;
// upper_tag_ = lower_tag_ + 0x10;
// upper_id_ = lower_id_;
} else {
lower_tag_ = tag;
lower_id_ = id;
upper_tag_ = lower_tag_;
upper_id_ = lower_id_;
}
// keep track of bounds as we descend down the tree // keep track of bounds as we descend down the tree
// //
// this gets a bit confusing as we also may need to keep // this gets a bit confusing as we also may need to keep
@@ -2052,7 +2071,7 @@ static int lfsr_rbyd_append(lfs_t *lfs, lfsr_rbyd_t *rbyd_,
upper_lower_id = lower_lower_id; upper_lower_id = lower_lower_id;
upper_upper_id = lower_upper_id; upper_upper_id = lower_upper_id;
upper_lower_tag = lower_lower_tag; upper_lower_tag = lower_lower_tag;
upper_upper_tag = lower_lower_tag; upper_upper_tag = lower_upper_tag;
} }
// prune? // prune?
@@ -2066,16 +2085,50 @@ static int lfsr_rbyd_append(lfs_t *lfs, lfsr_rbyd_t *rbyd_,
// | | .----'| | .----'| | // | | .----'| | .----'| |
// 1 2 3 4 4 1 2 3 4 4 2 // 1 2 3 4 4 1 2 3 4 4 2
bool prune = false; bool prune = false;
printf("0x%x %d (0x%x %d, 0x%x %d)\n", alt, weight_, lower_lower_tag, lower_lower_id, lower_upper_tag, lower_upper_id); printf("%c 0x%x w%d 0x%x (0x%x %d, 0x%x %d) f=%d (0x%x %d)\n",
if (weight_ >= (lfs_size_t)(lower_upper_id-lower_lower_id) !diverged
// TODO does this work if id weight > 1? ? '='
|| ((lfs_size_t)(lower_upper_id-lower_lower_id) == 1 : (lower_id_ < upper_id_
|| (lower_id_ == upper_id_
&& lower_tag_ < upper_tag_))
? '['
: ']',
alt, weight_, jump, lower_lower_tag, lower_lower_id, lower_upper_tag, lower_upper_id,
lfsr_tag_follow(alt, weight_,
lower_lower_id, lower_upper_id,
lower_tag_, lower_id_),
lower_tag_, lower_id_);
LFS_ASSERT(lower_upper_id - lower_lower_id >= 1);
// TODO something better than this
lfsr_tag_t predicted_lower_tag = lower_lower_tag;
lfsr_tag_t predicted_upper_tag = lower_upper_tag;
// if (p_alts[0] && lfsr_tag_isred(p_alts[0])) {
// // TODO need this?
// lfsr_tag_trimtag(p_alts[0],
// lower_lower_id, lower_upper_id,
// &predicted_lower_tag, &predicted_upper_tag,
// lower_id_);
// }
// TODO can this be rewritten in terms of lfsr_tag_follow?
if (weight_ > (lfs_size_t)(lower_upper_id-lower_lower_id-1)
|| (weight_ == (lfs_size_t)(lower_upper_id-lower_lower_id-1)
// TODO need key? // TODO need key?
&& (lfsr_tag_key(alt) && (lfsr_tag_isgt(alt)
< lfsr_tag_key(lower_lower_tag) ? lfsr_tag_key(predicted_lower_tag) > lfsr_tag_key(alt)
|| lfsr_tag_key(alt) : lfsr_tag_key(predicted_upper_tag-0x10) <= lfsr_tag_key(alt)))) {
>= lfsr_tag_key(lower_upper_tag)))) { // && (lfsr_tag_key(alt)
// < lfsr_tag_key(lower_lower_tag)
// || lfsr_tag_key(alt)
// >= lfsr_tag_key(lower_upper_tag)))) {
printf("PRUUUUUUUUUUUUUUUUUUUUUUUNE\n");
printf("%d > %d-%d-1 => %d\n", weight_, lower_upper_id, lower_lower_id, weight_ > (lfs_size_t)(lower_upper_id-lower_lower_id-1));
printf("%d == %d-%d-1 => %d\n", weight_, lower_upper_id, lower_lower_id, weight_ == (lfs_size_t)(lower_upper_id-lower_lower_id-1));
printf("isgt = %d\n", lfsr_tag_isgt(alt));
printf("0x%x > 0x%x => %d\n", lfsr_tag_key(predicted_lower_tag), lfsr_tag_key(alt), lfsr_tag_key(predicted_lower_tag) > lfsr_tag_key(alt));
printf("0x%x <= 0x%x => %d\n", lfsr_tag_key(predicted_upper_tag-0x10), lfsr_tag_key(alt), lfsr_tag_key(predicted_upper_tag-0x10) <= lfsr_tag_key(alt));
prune = true; prune = true;
// lower_lower_tag = predicted_lower_tag;
// lower_upper_tag = predicted_upper_tag;
// cut while following // cut while following
} else if (diverged } else if (diverged
&& lfsr_tag_follow(alt, weight_, && lfsr_tag_follow(alt, weight_,
@@ -2086,9 +2139,15 @@ static int lfsr_rbyd_append(lfs_t *lfs, lfsr_rbyd_t *rbyd_,
== lfsr_tag_isle(alt)) { == lfsr_tag_isle(alt)) {
lfsr_tag_trimweight( lfsr_tag_trimweight(
lfsr_tag_flipalt(alt), lfsr_tag_flipalt(alt),
lfsr_tag_flipweight(alt, weight_, lfsr_tag_flipweight(weight_,
lower_lower_id, lower_upper_id), lower_lower_id, lower_upper_id),
&lower_lower_id, &lower_upper_id); &lower_lower_id, &lower_upper_id);
lfsr_tag_trimtag(
lfsr_tag_flipalt(alt),
lower_lower_id, lower_upper_id,
&lower_lower_tag, &lower_upper_tag,
lower_id_);
printf("trim-f\n");
prune = true; prune = true;
// cut while not following // cut while not following
} else if (diverged } else if (diverged
@@ -2100,12 +2159,27 @@ static int lfsr_rbyd_append(lfs_t *lfs, lfsr_rbyd_t *rbyd_,
!= lfsr_tag_isle(alt)) { != lfsr_tag_isle(alt)) {
lfsr_tag_trimweight(alt, weight_, lfsr_tag_trimweight(alt, weight_,
&lower_lower_id, &lower_upper_id); &lower_lower_id, &lower_upper_id);
lfsr_tag_trimtag(alt,
lower_lower_id, lower_upper_id,
&lower_lower_tag, &lower_upper_tag,
lower_id_);
lfs_swap32(&jump, &branch_); lfs_swap32(&jump, &branch_);
printf("trim-nf\n");
prune = true; prune = true;
} }
// if (diverged
// && lfsr_tag_follow(alt, weight_,
// lower_lower_id, lower_upper_id,
// lower_tag_, lower_id_)) {
// printf("? %d || %d == %d\n",
// (lower_id_ < upper_id_),
// (lower_id_ == upper_id_ && lower_tag_ < upper_tag_),
// lfsr_tag_isle(alt));
// printf("(0x%x %d) (0x%x %d)\n", lower_tag_, lower_id_, upper_tag_, upper_id_);
// }
if (prune) { if (prune) {
printf("PRUUUUUUUUUUUUUUUUUUUUUUUNE\n");
if (p_alts[0] && lfsr_tag_isred(p_alts[0])) { if (p_alts[0] && lfsr_tag_isred(p_alts[0])) {
alt = lfsr_tag_mkblack(p_alts[0]); alt = lfsr_tag_mkblack(p_alts[0]);
weight_ = p_weights[0]; weight_ = p_weights[0];
@@ -2145,7 +2219,7 @@ static int lfsr_rbyd_append(lfs_t *lfs, lfsr_rbyd_t *rbyd_,
lfs_swap32(&jump, &p_jumps[0]); lfs_swap32(&jump, &p_jumps[0]);
p_alts[0] = lfsr_tag_mkblack( p_alts[0] = lfsr_tag_mkblack(
lfsr_tag_flipalt(p_alts[0])); lfsr_tag_flipalt(p_alts[0]));
p_weights[0] = lfsr_tag_flipweight(p_alts[0], p_weights[0], p_weights[0] = lfsr_tag_flipweight(p_weights[0],
lower_lower_id, lower_upper_id); lower_lower_id, lower_upper_id);
alt = lfsr_tag_mkblack(alt); alt = lfsr_tag_mkblack(alt);
@@ -2194,7 +2268,7 @@ static int lfsr_rbyd_append(lfs_t *lfs, lfsr_rbyd_t *rbyd_,
lower_lower_id, lower_upper_id, lower_lower_id, lower_upper_id,
lower_tag_, lower_id_)) { lower_tag_, lower_id_)) {
alt = lfsr_tag_flipalt(alt); alt = lfsr_tag_flipalt(alt);
weight_ = lfsr_tag_flipweight(alt, weight_, weight_ = lfsr_tag_flipweight(weight_,
lower_lower_id, lower_upper_id); lower_lower_id, lower_upper_id);
lfs_swap32(&jump, &branch_); lfs_swap32(&jump, &branch_);
} }
@@ -2213,6 +2287,7 @@ static int lfsr_rbyd_append(lfs_t *lfs, lfsr_rbyd_t *rbyd_,
LFS_ASSERT(lfsr_tag_isblack(alt)); LFS_ASSERT(lfsr_tag_isblack(alt));
lfs_swap16(&alt, &p_alts[0]); lfs_swap16(&alt, &p_alts[0]);
LFS_ASSERT(weight_ >= 0);
lfs_swap32(&weight_, &p_weights[0]); lfs_swap32(&weight_, &p_weights[0]);
lfs_swap32(&jump, &p_jumps[0]); lfs_swap32(&jump, &p_jumps[0]);
p_alts[0] = lfsr_tag_mkred(p_alts[0]); p_alts[0] = lfsr_tag_mkred(p_alts[0]);
@@ -2223,13 +2298,17 @@ static int lfsr_rbyd_append(lfs_t *lfs, lfsr_rbyd_t *rbyd_,
lfsr_tag_trimweight(p_alts[0], p_weights[0], lfsr_tag_trimweight(p_alts[0], p_weights[0],
&lower_lower_id, &lower_upper_id); &lower_lower_id, &lower_upper_id);
printf("whh? 0x%x w%d 0x%x\n", alt, weight_, jump);
printf("www? (0x%x w%d, 0x%x w%d)\n", 0, lower_lower_id, 0, upper_upper_id);
alt = lfsr_tag_flipalt(alt); alt = lfsr_tag_flipalt(alt);
weight_ = lfsr_tag_flipweight(alt, weight_, weight_ = lfsr_tag_flipweight(weight_,
lower_lower_id, lower_upper_id); lower_lower_id, lower_upper_id);
lfs_swap32(&jump, &branch_); lfs_swap32(&jump, &branch_);
printf("waa? 0x%x w%d 0x%x\n", alt, weight_, jump);
} }
// push alt onto queue // push alt onto queue
LFS_ASSERT((lfs_ssize_t)weight_ >= 0);
int err = lfsr_rbyd_p_push(lfs, rbyd_, int err = lfsr_rbyd_p_push(lfs, rbyd_,
p_alts, p_weights, p_jumps, p_alts, p_weights, p_jumps,
alt, weight_, jump); alt, weight_, jump);
@@ -2303,50 +2382,74 @@ stem:;
lfs_size_t weight = 0; lfs_size_t weight = 0;
lfs_off_t jump = 0; lfs_off_t jump = 0;
printf("! (0x%x %d) < (0x%x %d) < (0x%x %d)\n", lower_tag_, lower_id_, tag, id, upper_tag_, upper_id_);
if (lfsr_tag_isrm(lower_tag_)) { if (lfsr_tag_isrm(lower_tag_)) {
// no split needed, prune the removed tag // no split needed, prune the removed tag
} else if (lower_id_ < id } else if (lower_id_ < id
|| (lower_id_ == id || (lower_id_ == id
&& lfsr_tag_key(lower_tag_) < lfsr_tag_key(tag))) { && lfsr_tag_key(lower_tag_) < lfsr_tag_key(tag))
// split less than || (lower_id_ == id
// && tag == LFSR_TAG_RM
// note this is consistent for all appends and only happens when && !(upper_id_ > id))) {
// appending to the end of the tree // TODO ugh, separate RM condition?
alt = LFSR_TAG_ALT(B, LE, lower_tag_); if (tag == LFSR_TAG_RM) {
weight = lower_id_ - lower_lower_id; alt = LFSR_TAG_ALT(B, LE, 0xffff); // TODO hm, was trying to avoid this
jump = lower_branch; weight = lower_id_ - lower_lower_id - 1;
jump = lower_branch;
} else {
// split less than
//
// note this is consistent for all appends and only happens when
// appending to the end of the tree
alt = LFSR_TAG_ALT(B, LE, lower_tag_);
weight = lower_id_ - lower_lower_id;
jump = lower_branch;
}
} else if (lfsr_tag_ismk(tag)) { } else if (lfsr_tag_ismk(tag)) {
if (upper_id_ >= id) { if (upper_id_ >= id) {
// increase weight when creating
alt = LFSR_TAG_ALT(B, GT, tag); alt = LFSR_TAG_ALT(B, GT, tag);
weight = (upper_upper_id-1 - id) + 1; weight = upper_upper_id - id - 1 + 1;
jump = upper_branch; jump = upper_branch;
} }
// } else if (lfsr_tag_suptype(tag) == LFSR_TAG_RM) { } else if (tag == LFSR_TAG_RM) {
// if (lfsr_tag_weight(upper_tag_) // if (lfsr_tag_weight(upper_tag_)
// >= lfsr_tag_weight(tag & ~0x7fff)+0x8000) { // >= lfsr_tag_weight(tag & ~0x7fff)+0x8000) {
// // decrease biased weight when deleting if (upper_id_ > id) {
// alt = LFSR_ALT(B, GT, // decrease weight when deleting
// upper_upper-0x8000 - lower_lower); alt = LFSR_TAG_ALT(B, GT, 0);
// jump = upper_branch; printf("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH\n");
// } weight = upper_upper_id - lower_lower_id - 1;
// printf("%d = %d - %d - 1\n", weight, upper_upper_id, lower_lower_id);
// } else if (lfsr_tag_isrm(tag)) { jump = upper_branch;
}
} else if (lfsr_tag_isrm(tag)) {
if (upper_id_ > id
|| (upper_id_ == id
&& lfsr_tag_key(upper_tag_) > lfsr_tag_key(tag))) {
// hide our tag during removes
alt = LFSR_TAG_ALT(B, GT, 0);
weight = upper_upper_id - lower_lower_id;
jump = upper_branch;
}
// if (lfsr_tag_weight(upper_tag_) > lfsr_tag_weight(tag)) { // if (lfsr_tag_weight(upper_tag_) > lfsr_tag_weight(tag)) {
// // hide our tag during removes // // hide our tag during removes
// alt = LFSR_ALT(B, GT, // alt = LFSR_ALT(B, GT,
// upper_upper - lower_lower); // upper_upper - lower_lower);
// jump = upper_branch; // jump = upper_branch;
// } // }
//
} else if (upper_id_ > id } else if (upper_id_ > id
|| (upper_id_ == id || (upper_id_ == id
&& lfsr_tag_key(upper_tag_) > lfsr_tag_key(tag))) { && lfsr_tag_key(upper_tag_) > lfsr_tag_key(tag))) {
// split greater than // split greater than
alt = LFSR_TAG_ALT(B, GT, tag); alt = LFSR_TAG_ALT(B, GT, tag);
weight = upper_upper_id-1 - id; weight = upper_upper_id - id - 1;
jump = upper_branch; jump = upper_branch;
} }
@@ -2393,6 +2496,8 @@ leaf:;
// //
if (lfsr_tag_ismk(tag)) { if (lfsr_tag_ismk(tag)) {
rbyd_->weight += 1; rbyd_->weight += 1;
} else if (tag == LFSR_TAG_RM) {
rbyd_->weight -= 1;
} }
return 0; return 0;
+63 -58
View File
@@ -57,15 +57,21 @@ def tagrepr(tag, id, size, off=None):
'branch' if ((tag & 0x3f0) >> 4) == 0x00 'branch' if ((tag & 0x3f0) >> 4) == 0x00
else 'reg' if ((tag & 0x3f0) >> 4) == 0x01 else 'reg' if ((tag & 0x3f0) >> 4) == 0x01
else 'dir' if ((tag & 0x3f0) >> 4) == 0x02 else 'dir' if ((tag & 0x3f0) >> 4) == 0x02
else ' 0x%02x' % subtype, else ' 0x%02x' % ((tag & 0x3f0) >> 4),
id, id,
size) size)
elif (tag & ~0x3f0) == 0x0402:
return 'rm%s id%d%s' % (
' 0x%02x' % ((tag & 0x3f0) >> 4)
if ((tag & 0x3f0) >> 4) else '',
id,
' %d' % size if size else '')
elif (tag & ~0xff2) == 0x2000: elif (tag & ~0xff2) == 0x2000:
return '%suattr 0x%02x%s%s' % ( return '%suattr 0x%02x%s%s' % (
'rm' if tag & 0x1 else '', 'rm' if tag & 0x2 else '',
(tag & 0xff0) >> 4, (tag & 0xff0) >> 4,
' id%d' % id if id != -1 else '', ' id%d' % id if id != -1 else '',
' %d' % size if not tag & 0x1 else '') ' %d' % size if not tag & 0x2 or size else '')
elif (tag & ~0x10) == 0x24: elif (tag & ~0x10) == 0x24:
return 'crc%x%s %d' % ( return 'crc%x%s %d' % (
1 if tag & 0x10 else 0, 1 if tag & 0x10 else 0,
@@ -154,66 +160,64 @@ def show_log(block_size, data, rev, off, *,
# preprocess lifetimes # preprocess lifetimes
if args.get('lifetimes'): if args.get('lifetimes'):
count = 0 weight = 0
max_count = 0 max_weight = 0
lifetimes = {} lifetimes = {}
ids = [] ids = []
ids_i = 0 ids_i = 0
j_ = 4 j_ = 4
while j_ < (block_size if args.get('all') else off): while j_ < (block_size if args.get('all') else off):
j = j_ j = j_
v, tag, size, delta = fromtag(data[j_:]) v, tag, id, size, delta = fromtag(data[j_:])
j_ += delta j_ += delta
if not tag & 0x4: if not tag & 0x8:
j_ += size j_ += size
if (tag & 0x7807) == 0x0800: if (tag & ~0x3f0) == 0x0400:
count += 1 weight += 1
max_count = max(max_count, count) max_weight = max(max_weight, weight)
ids.insert(((tag >> 15) & 0xffff)-1, ids.insert(id, COLORS[ids_i % len(COLORS)])
COLORS[ids_i % len(COLORS)])
ids_i += 1 ids_i += 1
lifetimes[j] = ( lifetimes[j] = (
''.join( ''.join(
'%s%s%s' % ( '%s%s%s' % (
'\x1b[%sm' % ids[id] if color else '', '\x1b[%sm' % ids[id_] if color else '',
'.' if id == ((tag >> 15) & 0xffff)-1 '.' if id_ == id
else '\ ' if id > ((tag >> 15) & 0xffff)-1 else '\ ' if id_ > id
else '| ', else '| ',
'\x1b[m' if color else '') '\x1b[m' if color else '')
for id in range(count)) for id_ in range(weight))
+ ' ', + ' ',
count) weight)
elif ((tag & 0x7807) == 0x0801 elif ((tag & ~0x3f0) == 0x0402 and id < len(ids)):
and ((tag >> 15) & 0xffff)-1 < len(ids)):
lifetimes[j] = ( lifetimes[j] = (
''.join( ''.join(
'%s%s%s' % ( '%s%s%s' % (
'\x1b[%sm' % ids[id] if color else '', '\x1b[%sm' % ids[id_] if color else '',
'\'' if id == ((tag >> 15) & 0xffff)-1 '\'' if id_ == id
else '/ ' if id > ((tag >> 15) & 0xffff)-1 else '/ ' if id_ > id
else '| ', else '| ',
'\x1b[m' if color else '') '\x1b[m' if color else '')
for id in range(count)) for id_ in range(weight))
+ ' ', + ' ',
count) weight)
count -= 1 weight -= 1
ids.pop(((tag >> 15) & 0xffff)-1) ids.pop(id)
else: else:
lifetimes[j] = ( lifetimes[j] = (
''.join( ''.join(
'%s%s%s' % ( '%s%s%s' % (
'\x1b[%sm' % ids[id] if color else '', '\x1b[%sm' % ids[id_] if color else '',
'* ' if not tag & 0x4 '* ' if not tag & 0x8
and id == ((tag >> 15) & 0xffff)-1 and id_ == id
else '| ', else '| ',
'\x1b[m' if color else '') '\x1b[m' if color else '')
for id in range(count)), for id_ in range(weight)),
count) weight)
def lifetimerepr(j): def lifetimerepr(j):
lifetime, count = lifetimes.get(j, ('', 0)) lifetime, weight = lifetimes.get(j, ('', 0))
return '%s%*s' % (lifetime, 2*(max_count-count), '') return '%s%*s' % (lifetime, 2*(max_weight-weight), '')
# prepare other things # prepare other things
if args.get('rbyd'): if args.get('rbyd'):
@@ -254,13 +258,13 @@ def show_log(block_size, data, rev, off, *,
notes.append('crc!=%08x' % crc) notes.append('crc!=%08x' % crc)
j_ += size j_ += size
# # adjust count? # # adjust weight?
# if args.get('lifetimes'): # if args.get('lifetimes'):
# if (tag & 0x7807) == 0x0800: # if (tag & ~0x3f0) == 0x0400:
# count += 1 # weight += 1
# elif ((tag & 0x7807) == 0x0801 # elif ((tag & ~0x3f0) == 0x0402
# and ((tag >> 15) & 0xffff)-1 < len(ids)): # and ((tag >> 15) & 0xffff)-1 < len(ids)):
# count -= 1 # weight -= 1
# show human-readable tag representation # show human-readable tag representation
print('%s%08x:%s %s%s%-57s%s%s' % ( print('%s%08x:%s %s%s%-57s%s%s' % (
@@ -336,7 +340,7 @@ def show_log(block_size, data, rev, off, *,
alts = [] alts = []
def show_tree(block_size, data, rev, trunk, count, *, def show_tree(block_size, data, rev, trunk, weight, *,
color=False, color=False,
**args): **args):
if trunk is None: if trunk is None:
@@ -346,7 +350,7 @@ def show_tree(block_size, data, rev, trunk, count, *,
# purposes # purposes
def lookup(tag): def lookup(tag):
lower = 0 lower = 0
upper = (count+1) << 15 upper = (weight+1) << 15
path = [] path = []
# descend down tree # descend down tree
@@ -578,8 +582,8 @@ def main(disk, block_size, block1, block2=None, *,
j_ = 4 j_ = 4
trunk = None trunk = None
trunk_ = None trunk_ = None
count = 0 weight = 0
count_ = 0 weight_ = 0
wastrunk = False wastrunk = False
while j_ < block_size: while j_ < block_size:
v, tag, id, size, delta = fromtag(data[j_:]) v, tag, id, size, delta = fromtag(data[j_:])
@@ -595,11 +599,11 @@ def main(disk, block_size, block1, block2=None, *,
if not tag & 0x8: if not tag & 0x8:
if (tag & ~0x10) != 0x24: if (tag & ~0x10) != 0x24:
crc = crc32c(data[j_:j_+size], crc) crc = crc32c(data[j_:j_+size], crc)
# # keep track of id count # keep track of weight
# if (tag & 0x7807) == 0x0800: if (tag & ~0x3f0) == 0x0400:
# count_ += 1 weight_ += 1
# elif (tag & 0x7807) == 0x0801: elif (tag & ~0x3f0) == 0x0402:
# count_ = max(count_ - 1, 0) weight_ = max(weight_ - 1, 0)
# found a crc? # found a crc?
else: else:
crc_, = struct.unpack('<I', data[j_:j_+4].ljust(4, b'\0')) crc_, = struct.unpack('<I', data[j_:j_+4].ljust(4, b'\0'))
@@ -608,34 +612,35 @@ def main(disk, block_size, block1, block2=None, *,
# commit what we have # commit what we have
off = j_ + size off = j_ + size
trunk = trunk_ trunk = trunk_
count = count_ weight = weight_
j_ += size j_ += size
wastrunk = False wastrunk = False
return rev, off, trunk, count return rev, off, trunk, weight
revs, offs, trunks, counts = [], [], [], [] revs, offs, trunks, weights = [], [], [], []
i = 0 i = 0
for block, data in zip(blocks, datas): for block, data in zip(blocks, datas):
rev, off, trunk_, count = fetch(data) rev, off, trunk_, weight = fetch(data)
revs.append(rev) revs.append(rev)
offs.append(off) offs.append(off)
trunks.append(trunk_) trunks.append(trunk_)
counts.append(count) weights.append(weight)
# compare with sequence arithmetic # compare with sequence arithmetic
if off and ((rev - revs[i]) & 0x80000000): if off and ((rev - revs[i]) & 0x80000000):
i = len(revs)-1 i = len(revs)-1
# print contents of the winning metadata block # print contents of the winning metadata block
block, data, rev, off, trunk, count = ( block, data, rev, off, trunk, weight = (
blocks[i], datas[i], revs[i], offs[i], blocks[i], datas[i], revs[i], offs[i],
trunk if trunk is not None else trunks[i], trunk if trunk is not None else trunks[i],
counts[i]) weights[i])
print('mdir 0x%x, rev %d, size %d%s' % ( print('mdir 0x%x, rev %d, size %d, weight %d%s' % (
block, rev, off, block, rev, off, weight,
' (was 0x%x, %d, %d)' % (blocks[~i], revs[~i], offs[~i]) ' (was 0x%x, %d, %d, %d)' % (
blocks[~i], revs[~i], offs[~i], weights[~i])
if len(blocks) > 1 else '')) if len(blocks) > 1 else ''))
if args.get('log'): if args.get('log'):
@@ -643,7 +648,7 @@ def main(disk, block_size, block1, block2=None, *,
color=color, color=color,
**args) **args)
else: else:
show_tree(block_size, data, rev, trunk, count, show_tree(block_size, data, rev, trunk, weight,
color=color, color=color,
**args) **args)
+1730 -1568
View File
File diff suppressed because it is too large Load Diff