WIP Stage 1 of B-trees with separate child slots
Startingto run into some problems, not using separate child slots may end up working better, even if it it's imperfect
This commit is contained in:
@@ -552,7 +552,6 @@ static int lfs_commit_move(lfs_t *lfs, struct lfs_commit *commit,
|
|||||||
|
|
||||||
struct lfs_commit_split {
|
struct lfs_commit_split {
|
||||||
uint16_t fromid;
|
uint16_t fromid;
|
||||||
uint16_t toid;
|
|
||||||
uint16_t count;
|
uint16_t count;
|
||||||
bool delete;
|
bool delete;
|
||||||
bool branch;
|
bool branch;
|
||||||
@@ -562,7 +561,7 @@ struct lfs_commit_split {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static int lfs_commit_split(lfs_t *lfs, struct lfs_commit *commit,
|
static int lfs_commit_split(lfs_t *lfs, struct lfs_commit *commit,
|
||||||
const struct lfs_commit_split *split);
|
uint16_t id, const struct lfs_commit_split *split);
|
||||||
|
|
||||||
static int lfs_commit_attr(lfs_t *lfs, struct lfs_commit *commit,
|
static int lfs_commit_attr(lfs_t *lfs, struct lfs_commit *commit,
|
||||||
uint32_t tag, const void *buffer) {
|
uint32_t tag, const void *buffer) {
|
||||||
@@ -575,7 +574,8 @@ static int lfs_commit_attr(lfs_t *lfs, struct lfs_commit *commit,
|
|||||||
buffer, NULL);
|
buffer, NULL);
|
||||||
} else if (lfs_tag_type(tag) == LFS_FROM_SPLIT) {
|
} else if (lfs_tag_type(tag) == LFS_FROM_SPLIT) {
|
||||||
// specail case for feeding commits from tail lists
|
// specail case for feeding commits from tail lists
|
||||||
return lfs_commit_split(lfs, commit, buffer);
|
return lfs_commit_split(lfs, commit,
|
||||||
|
lfs_tag_id(tag), buffer);
|
||||||
} else if (lfs_tag_type(tag) == LFS_FROM_ATTRS) {
|
} else if (lfs_tag_type(tag) == LFS_FROM_ATTRS) {
|
||||||
// special case for custom attributes
|
// special case for custom attributes
|
||||||
return lfs_commit_attrs(lfs, commit,
|
return lfs_commit_attrs(lfs, commit,
|
||||||
@@ -733,39 +733,34 @@ static int lfs_commit_move(lfs_t *lfs, struct lfs_commit *commit,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int lfs_commit_split(lfs_t *lfs, struct lfs_commit *commit,
|
static int lfs_commit_split(lfs_t *lfs, struct lfs_commit *commit,
|
||||||
const struct lfs_commit_split *split) {
|
uint16_t toid, const struct lfs_commit_split *split) {
|
||||||
if (split->delete) {
|
|
||||||
int err = lfs_commit_attr(lfs, commit,
|
|
||||||
LFS_MKTAG(LFS_TYPE_DELETE, split->toid, 0), NULL);
|
|
||||||
if (err) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t fromid = split->fromid;
|
uint16_t fromid = split->fromid;
|
||||||
uint16_t count = split->count;
|
uint16_t count = split->count;
|
||||||
bool branch = split->branch;
|
bool branch = split->branch;
|
||||||
|
bool delete = split->delete;
|
||||||
while (count > 0) {
|
while (count > 0) {
|
||||||
if (branch) {
|
if (branch) {
|
||||||
|
if (!delete) {
|
||||||
int err = lfs_commit_attr(lfs, commit,
|
int err = lfs_commit_attr(lfs, commit,
|
||||||
LFS_MKTAG(LFS_TYPE_CHILD, split->toid, 0), NULL);
|
LFS_MKTAG(LFS_TYPE_CHILD, toid, 0), NULL);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
delete = false;
|
||||||
|
}
|
||||||
|
|
||||||
err = lfs_commit_attr(lfs, commit,
|
int err = lfs_commit_attr(lfs, commit,
|
||||||
LFS_MKTAG(LFS_TYPE_DIRSTRUCT, split->toid, 8),
|
LFS_MKTAG(LFS_TYPE_DIRSTRUCT, toid, 8),
|
||||||
split->child->pair);
|
split->child->pair);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("split %d (%d)\n", split->child->count, count);
|
|
||||||
count -= split->child->count;
|
count -= split->child->count;
|
||||||
fromid -= split->child->count;
|
fromid -= split->child->count;
|
||||||
|
|
||||||
if (count >= 2) {
|
if (count >= 2) {
|
||||||
printf("tail %x %x\n", split->child->tail[0], split->child->tail[1]);
|
|
||||||
err = lfs_dir_fetch(lfs, split->child, split->child->tail);
|
err = lfs_dir_fetch(lfs, split->child, split->child->tail);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
@@ -774,13 +769,12 @@ static int lfs_commit_split(lfs_t *lfs, struct lfs_commit *commit,
|
|||||||
} else {
|
} else {
|
||||||
int err = lfs_commit_move(lfs, commit,
|
int err = lfs_commit_move(lfs, commit,
|
||||||
0x003ff000, LFS_MKTAG(0, fromid, 0),
|
0x003ff000, LFS_MKTAG(0, fromid, 0),
|
||||||
0x003ff000, LFS_MKTAG(0, split->toid, 0),
|
0x003ff000, LFS_MKTAG(0, toid, 0),
|
||||||
split->source, split->attrs);
|
split->source, split->attrs);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("betwe %d (%d)\n", 1, count);
|
|
||||||
count -= 1;
|
count -= 1;
|
||||||
fromid -= 1;
|
fromid -= 1;
|
||||||
}
|
}
|
||||||
@@ -1352,7 +1346,7 @@ static int lfs_dir_compact2_(lfs_t *lfs,
|
|||||||
for (uint16_t id = begin; id < end; id++) {
|
for (uint16_t id = begin; id < end; id++) {
|
||||||
err = lfs_commit_move(lfs, &commit,
|
err = lfs_commit_move(lfs, &commit,
|
||||||
0x003ff000, LFS_MKTAG(0, id, 0),
|
0x003ff000, LFS_MKTAG(0, id, 0),
|
||||||
0x003ff000, LFS_MKTAG(0, id - begin, 0),
|
0x003ff000, LFS_MKTAG(0, commit.count, 0),
|
||||||
source, attrs);
|
source, attrs);
|
||||||
if (err) {
|
if (err) {
|
||||||
if (err == LFS_ERR_NOSPC) {
|
if (err == LFS_ERR_NOSPC) {
|
||||||
@@ -1514,7 +1508,6 @@ int lfs_dir_split(lfs_t *lfs,
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("got %d\n", child.count);
|
|
||||||
begin += child.count;
|
begin += child.count;
|
||||||
children += child.count;
|
children += child.count;
|
||||||
ncount += 1;
|
ncount += 1;
|
||||||
@@ -1531,6 +1524,7 @@ int lfs_dir_split(lfs_t *lfs,
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct lfs_commit_split split;
|
struct lfs_commit_split split;
|
||||||
|
uint16_t toid;
|
||||||
split.fromid = end-1;
|
split.fromid = end-1;
|
||||||
split.count = children;
|
split.count = children;
|
||||||
split.child = &child;
|
split.child = &child;
|
||||||
@@ -1558,17 +1552,17 @@ int lfs_dir_split(lfs_t *lfs,
|
|||||||
parent.off = 0;
|
parent.off = 0;
|
||||||
parent.erased = false;
|
parent.erased = false;
|
||||||
split.delete = false;
|
split.delete = false;
|
||||||
split.toid = 0;
|
toid = 0;
|
||||||
} else {
|
} else {
|
||||||
// TODO update tail in this case
|
// TODO update tail in this case
|
||||||
parent.tail[0] = dir->tail[0];
|
parent.tail[0] = dir->tail[0];
|
||||||
parent.tail[1] = dir->tail[1];
|
parent.tail[1] = dir->tail[1];
|
||||||
split.delete = true;
|
split.delete = true;
|
||||||
split.toid = lfs_tag_id(tag);
|
toid = lfs_tag_id(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
return lfs_dir_commit(lfs, &parent, ncount - split.delete,
|
return lfs_dir_commit(lfs, &parent, ncount - split.delete,
|
||||||
LFS_MKATTR(LFS_FROM_SPLIT, split.toid, &split, 0,
|
LFS_MKATTR(LFS_FROM_SPLIT, toid, &split, 0,
|
||||||
NULL));
|
NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user