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:
Christopher Haster
2018-09-05 05:07:22 -05:00
parent 8e501d5922
commit 227936b043

48
lfs.c
View File

@@ -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) {
int err = lfs_commit_attr(lfs, commit, if (!delete) {
LFS_MKTAG(LFS_TYPE_CHILD, split->toid, 0), NULL); int err = lfs_commit_attr(lfs, commit,
if (err) { LFS_MKTAG(LFS_TYPE_CHILD, toid, 0), NULL);
return err; if (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));
} }