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

289
lfs.c
View File

@@ -457,13 +457,15 @@ enum lfsr_tag_type {
LFSR_TAG_MKBRANCH = 0x0400,
LFSR_TAG_MKREG = 0x0410,
LFSR_TAG_MKDIR = 0x0420,
LFSR_TAG_RM = 0x0402,
LFSR_TAG_UATTR = 0x2000,
LFSR_TAG_RMUATTR = 0x2001,
LFSR_TAG_RMUATTR = 0x2002,
LFSR_TAG_BTREE = 0x0820,
LFSR_TAG_EXPAND = 0x0004,
LFSR_TAG_SHRINK = 0x0014,
// TODO these
// LFSR_TAG_EXPAND = 0x0004,
// LFSR_TAG_SHRINK = 0x0014,
LFSR_TAG_ALT = 0x0008,
LFSR_TAG_ALTBLE = 0x0008,
@@ -491,6 +493,10 @@ enum lfsr_tag_type {
(LFSR_TAG_UATTR \
| ((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)
// (LFSR_TAG_ALT
// | ((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;
}
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) {
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???
if (lfsr_tag_isgt(alt)) {
if (id == upper_id-1) {
*upper_tag = alt;
*upper_tag = alt + 0x10;
}
} else {
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
weight += 1;
// 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;
}
} else if (tag == LFSR_TAG_RM) {
// 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_;
}
weight -= 1;
// TODO this
// // 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
} 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?
lfsr_tag_trimweight(
lfsr_tag_flipalt(alt),
lfsr_tag_flipweight(alt, weight_, lower, upper),
lfsr_tag_flipweight(weight_, lower, upper),
&lower, &upper);
branch = branch - jump;
} 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) {
// tags must be in a valid id range at this point
if (lfsr_tag_ismk(tag)) {
LFS_ASSERT(rbyd_->weight < 0xffff);
LFS_ASSERT(id <= rbyd_->weight);
} else {
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
lfs_off_t lower_branch = rbyd_->trunk;
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;
}
// 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
//
// 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_upper_id = lower_upper_id;
upper_lower_tag = lower_lower_tag;
upper_upper_tag = lower_lower_tag;
upper_upper_tag = lower_upper_tag;
}
// 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
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);
if (weight_ >= (lfs_size_t)(lower_upper_id-lower_lower_id)
// TODO does this work if id weight > 1?
|| ((lfs_size_t)(lower_upper_id-lower_lower_id) == 1
printf("%c 0x%x w%d 0x%x (0x%x %d, 0x%x %d) f=%d (0x%x %d)\n",
!diverged
? '='
: (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?
&& (lfsr_tag_key(alt)
< lfsr_tag_key(lower_lower_tag)
|| lfsr_tag_key(alt)
>= lfsr_tag_key(lower_upper_tag)))) {
&& (lfsr_tag_isgt(alt)
? lfsr_tag_key(predicted_lower_tag) > lfsr_tag_key(alt)
: lfsr_tag_key(predicted_upper_tag-0x10) <= lfsr_tag_key(alt)))) {
// && (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;
// lower_lower_tag = predicted_lower_tag;
// lower_upper_tag = predicted_upper_tag;
// cut while following
} else if (diverged
&& 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_trimweight(
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);
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;
// cut while not following
} 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_trimweight(alt, weight_,
&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_);
printf("trim-nf\n");
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) {
printf("PRUUUUUUUUUUUUUUUUUUUUUUUNE\n");
if (p_alts[0] && lfsr_tag_isred(p_alts[0])) {
alt = lfsr_tag_mkblack(p_alts[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]);
p_alts[0] = lfsr_tag_mkblack(
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);
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_tag_, lower_id_)) {
alt = lfsr_tag_flipalt(alt);
weight_ = lfsr_tag_flipweight(alt, weight_,
weight_ = lfsr_tag_flipweight(weight_,
lower_lower_id, lower_upper_id);
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_swap16(&alt, &p_alts[0]);
LFS_ASSERT(weight_ >= 0);
lfs_swap32(&weight_, &p_weights[0]);
lfs_swap32(&jump, &p_jumps[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],
&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);
weight_ = lfsr_tag_flipweight(alt, weight_,
weight_ = lfsr_tag_flipweight(weight_,
lower_lower_id, lower_upper_id);
lfs_swap32(&jump, &branch_);
printf("waa? 0x%x w%d 0x%x\n", alt, weight_, jump);
}
// push alt onto queue
LFS_ASSERT((lfs_ssize_t)weight_ >= 0);
int err = lfsr_rbyd_p_push(lfs, rbyd_,
p_alts, p_weights, p_jumps,
alt, weight_, jump);
@@ -2303,50 +2382,74 @@ stem:;
lfs_size_t weight = 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_)) {
// no split needed, prune the removed tag
} else if (lower_id_ < id
|| (lower_id_ == id
&& lfsr_tag_key(lower_tag_) < lfsr_tag_key(tag))) {
// 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;
&& 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
//
// 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)) {
if (upper_id_ >= id) {
// increase weight when creating
alt = LFSR_TAG_ALT(B, GT, tag);
weight = (upper_upper_id-1 - id) + 1;
weight = upper_upper_id - id - 1 + 1;
jump = upper_branch;
}
// } else if (lfsr_tag_suptype(tag) == LFSR_TAG_RM) {
} else if (tag == LFSR_TAG_RM) {
// if (lfsr_tag_weight(upper_tag_)
// >= lfsr_tag_weight(tag & ~0x7fff)+0x8000) {
// // decrease biased weight when deleting
// alt = LFSR_ALT(B, GT,
// upper_upper-0x8000 - lower_lower);
// jump = upper_branch;
// }
//
// } else if (lfsr_tag_isrm(tag)) {
if (upper_id_ > id) {
// decrease weight when deleting
alt = LFSR_TAG_ALT(B, GT, 0);
printf("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH\n");
weight = upper_upper_id - lower_lower_id - 1;
printf("%d = %d - %d - 1\n", weight, upper_upper_id, lower_lower_id);
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)) {
// // hide our tag during removes
// alt = LFSR_ALT(B, GT,
// upper_upper - lower_lower);
// jump = upper_branch;
// }
//
} else if (upper_id_ > id
|| (upper_id_ == id
&& lfsr_tag_key(upper_tag_) > lfsr_tag_key(tag))) {
// split greater than
alt = LFSR_TAG_ALT(B, GT, tag);
weight = upper_upper_id-1 - id;
weight = upper_upper_id - id - 1;
jump = upper_branch;
}
@@ -2393,6 +2496,8 @@ leaf:;
//
if (lfsr_tag_ismk(tag)) {
rbyd_->weight += 1;
} else if (tag == LFSR_TAG_RM) {
rbyd_->weight -= 1;
}
return 0;

View File

@@ -57,15 +57,21 @@ def tagrepr(tag, id, size, off=None):
'branch' if ((tag & 0x3f0) >> 4) == 0x00
else 'reg' if ((tag & 0x3f0) >> 4) == 0x01
else 'dir' if ((tag & 0x3f0) >> 4) == 0x02
else ' 0x%02x' % subtype,
else ' 0x%02x' % ((tag & 0x3f0) >> 4),
id,
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:
return '%suattr 0x%02x%s%s' % (
'rm' if tag & 0x1 else '',
'rm' if tag & 0x2 else '',
(tag & 0xff0) >> 4,
' 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:
return 'crc%x%s %d' % (
1 if tag & 0x10 else 0,
@@ -154,66 +160,64 @@ def show_log(block_size, data, rev, off, *,
# preprocess lifetimes
if args.get('lifetimes'):
count = 0
max_count = 0
weight = 0
max_weight = 0
lifetimes = {}
ids = []
ids_i = 0
j_ = 4
while j_ < (block_size if args.get('all') else off):
j = j_
v, tag, size, delta = fromtag(data[j_:])
v, tag, id, size, delta = fromtag(data[j_:])
j_ += delta
if not tag & 0x4:
if not tag & 0x8:
j_ += size
if (tag & 0x7807) == 0x0800:
count += 1
max_count = max(max_count, count)
ids.insert(((tag >> 15) & 0xffff)-1,
COLORS[ids_i % len(COLORS)])
if (tag & ~0x3f0) == 0x0400:
weight += 1
max_weight = max(max_weight, weight)
ids.insert(id, COLORS[ids_i % len(COLORS)])
ids_i += 1
lifetimes[j] = (
''.join(
'%s%s%s' % (
'\x1b[%sm' % ids[id] if color else '',
'.' if id == ((tag >> 15) & 0xffff)-1
else '\ ' if id > ((tag >> 15) & 0xffff)-1
'\x1b[%sm' % ids[id_] if color else '',
'.' if id_ == id
else '\ ' if id_ > id
else '| ',
'\x1b[m' if color else '')
for id in range(count))
for id_ in range(weight))
+ ' ',
count)
elif ((tag & 0x7807) == 0x0801
and ((tag >> 15) & 0xffff)-1 < len(ids)):
weight)
elif ((tag & ~0x3f0) == 0x0402 and id < len(ids)):
lifetimes[j] = (
''.join(
'%s%s%s' % (
'\x1b[%sm' % ids[id] if color else '',
'\'' if id == ((tag >> 15) & 0xffff)-1
else '/ ' if id > ((tag >> 15) & 0xffff)-1
'\x1b[%sm' % ids[id_] if color else '',
'\'' if id_ == id
else '/ ' if id_ > id
else '| ',
'\x1b[m' if color else '')
for id in range(count))
for id_ in range(weight))
+ ' ',
count)
count -= 1
ids.pop(((tag >> 15) & 0xffff)-1)
weight)
weight -= 1
ids.pop(id)
else:
lifetimes[j] = (
''.join(
'%s%s%s' % (
'\x1b[%sm' % ids[id] if color else '',
'* ' if not tag & 0x4
and id == ((tag >> 15) & 0xffff)-1
'\x1b[%sm' % ids[id_] if color else '',
'* ' if not tag & 0x8
and id_ == id
else '| ',
'\x1b[m' if color else '')
for id in range(count)),
count)
for id_ in range(weight)),
weight)
def lifetimerepr(j):
lifetime, count = lifetimes.get(j, ('', 0))
return '%s%*s' % (lifetime, 2*(max_count-count), '')
lifetime, weight = lifetimes.get(j, ('', 0))
return '%s%*s' % (lifetime, 2*(max_weight-weight), '')
# prepare other things
if args.get('rbyd'):
@@ -254,13 +258,13 @@ def show_log(block_size, data, rev, off, *,
notes.append('crc!=%08x' % crc)
j_ += size
# # adjust count?
# # adjust weight?
# if args.get('lifetimes'):
# if (tag & 0x7807) == 0x0800:
# count += 1
# elif ((tag & 0x7807) == 0x0801
# if (tag & ~0x3f0) == 0x0400:
# weight += 1
# elif ((tag & ~0x3f0) == 0x0402
# and ((tag >> 15) & 0xffff)-1 < len(ids)):
# count -= 1
# weight -= 1
# show human-readable tag representation
print('%s%08x:%s %s%s%-57s%s%s' % (
@@ -336,7 +340,7 @@ def show_log(block_size, data, rev, off, *,
alts = []
def show_tree(block_size, data, rev, trunk, count, *,
def show_tree(block_size, data, rev, trunk, weight, *,
color=False,
**args):
if trunk is None:
@@ -346,7 +350,7 @@ def show_tree(block_size, data, rev, trunk, count, *,
# purposes
def lookup(tag):
lower = 0
upper = (count+1) << 15
upper = (weight+1) << 15
path = []
# descend down tree
@@ -578,8 +582,8 @@ def main(disk, block_size, block1, block2=None, *,
j_ = 4
trunk = None
trunk_ = None
count = 0
count_ = 0
weight = 0
weight_ = 0
wastrunk = False
while j_ < block_size:
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 (tag & ~0x10) != 0x24:
crc = crc32c(data[j_:j_+size], crc)
# # keep track of id count
# if (tag & 0x7807) == 0x0800:
# count_ += 1
# elif (tag & 0x7807) == 0x0801:
# count_ = max(count_ - 1, 0)
# keep track of weight
if (tag & ~0x3f0) == 0x0400:
weight_ += 1
elif (tag & ~0x3f0) == 0x0402:
weight_ = max(weight_ - 1, 0)
# found a crc?
else:
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
off = j_ + size
trunk = trunk_
count = count_
weight = weight_
j_ += size
wastrunk = False
return rev, off, trunk, count
return rev, off, trunk, weight
revs, offs, trunks, counts = [], [], [], []
revs, offs, trunks, weights = [], [], [], []
i = 0
for block, data in zip(blocks, datas):
rev, off, trunk_, count = fetch(data)
rev, off, trunk_, weight = fetch(data)
revs.append(rev)
offs.append(off)
trunks.append(trunk_)
counts.append(count)
weights.append(weight)
# compare with sequence arithmetic
if off and ((rev - revs[i]) & 0x80000000):
i = len(revs)-1
# 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],
trunk if trunk is not None else trunks[i],
counts[i])
weights[i])
print('mdir 0x%x, rev %d, size %d%s' % (
block, rev, off,
' (was 0x%x, %d, %d)' % (blocks[~i], revs[~i], offs[~i])
print('mdir 0x%x, rev %d, size %d, weight %d%s' % (
block, rev, off, weight,
' (was 0x%x, %d, %d, %d)' % (
blocks[~i], revs[~i], offs[~i], weights[~i])
if len(blocks) > 1 else ''))
if args.get('log'):
@@ -643,7 +648,7 @@ def main(disk, block_size, block1, block2=None, *,
color=color,
**args)
else:
show_tree(block_size, data, rev, trunk, count,
show_tree(block_size, data, rev, trunk, weight,
color=color,
**args)

File diff suppressed because it is too large Load Diff