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:
@@ -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,12 +2382,23 @@ 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))
|
||||||
|
|| (lower_id_ == id
|
||||||
|
&& tag == LFSR_TAG_RM
|
||||||
|
&& !(upper_id_ > id))) {
|
||||||
|
// TODO ugh, separate RM condition?
|
||||||
|
if (tag == LFSR_TAG_RM) {
|
||||||
|
alt = LFSR_TAG_ALT(B, LE, 0xffff); // TODO hm, was trying to avoid this
|
||||||
|
weight = lower_id_ - lower_lower_id - 1;
|
||||||
|
jump = lower_branch;
|
||||||
|
} else {
|
||||||
// split less than
|
// split less than
|
||||||
//
|
//
|
||||||
// note this is consistent for all appends and only happens when
|
// note this is consistent for all appends and only happens when
|
||||||
@@ -2316,37 +2406,50 @@ stem:;
|
|||||||
alt = LFSR_TAG_ALT(B, LE, lower_tag_);
|
alt = LFSR_TAG_ALT(B, LE, lower_tag_);
|
||||||
weight = lower_id_ - lower_lower_id;
|
weight = lower_id_ - lower_lower_id;
|
||||||
jump = lower_branch;
|
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
@@ -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
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user