Reduce memory usage in low level tree, by storing dir info separately.
This commit is contained in:
parent
4b8db2f274
commit
7e66fe43ce
@ -51,8 +51,8 @@ print_dir(Ecma119Node *dir, int level)
|
||||
sp[level * 2-1] = '-';
|
||||
sp[level * 2] = '\0';
|
||||
|
||||
for (i = 0; i < dir->info.dir.nchildren; i++) {
|
||||
Ecma119Node *child = dir->info.dir.children[i];
|
||||
for (i = 0; i < dir->info.dir->nchildren; i++) {
|
||||
Ecma119Node *child = dir->info.dir->children[i];
|
||||
|
||||
if (child->type == ECMA119_DIR) {
|
||||
printf("%s+[D] ", sp);
|
||||
|
@ -106,9 +106,9 @@ size_t calc_dir_size(Ecma119Image *t, Ecma119Node *dir, size_t *ce)
|
||||
*ce += ce_len;
|
||||
}
|
||||
|
||||
for (i = 0; i < dir->info.dir.nchildren; ++i) {
|
||||
for (i = 0; i < dir->info.dir->nchildren; ++i) {
|
||||
size_t remaining;
|
||||
Ecma119Node *child = dir->info.dir.children[i];
|
||||
Ecma119Node *child = dir->info.dir->children[i];
|
||||
size_t dirent_len = calc_dirent_len(t, child);
|
||||
if (t->rockridge) {
|
||||
dirent_len += rrip_calc_len(t, child, 0, 255 - dirent_len, &ce_len);
|
||||
@ -123,7 +123,7 @@ size_t calc_dir_size(Ecma119Image *t, Ecma119Node *dir, size_t *ce)
|
||||
}
|
||||
}
|
||||
/* cache the len */
|
||||
dir->info.dir.len = len;
|
||||
dir->info.dir->len = len;
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -134,14 +134,14 @@ void calc_dir_pos(Ecma119Image *t, Ecma119Node *dir)
|
||||
size_t ce_len = 0;
|
||||
|
||||
t->ndirs++;
|
||||
dir->info.dir.block = t->curblock;
|
||||
dir->info.dir->block = t->curblock;
|
||||
len = calc_dir_size(t, dir, &ce_len);
|
||||
t->curblock += div_up(len, BLOCK_SIZE);
|
||||
if (t->rockridge) {
|
||||
t->curblock += div_up(ce_len, BLOCK_SIZE);
|
||||
}
|
||||
for (i = 0; i < dir->info.dir.nchildren; i++) {
|
||||
Ecma119Node *child = dir->info.dir.children[i];
|
||||
for (i = 0; i < dir->info.dir->nchildren; i++) {
|
||||
Ecma119Node *child = dir->info.dir->children[i];
|
||||
if (child->type == ECMA119_DIR) {
|
||||
calc_dir_pos(t, child);
|
||||
}
|
||||
@ -163,8 +163,8 @@ uint32_t calc_path_table_size(Ecma119Node *dir)
|
||||
size += (size % 2);
|
||||
|
||||
/* and recurse */
|
||||
for (i = 0; i < dir->info.dir.nchildren; i++) {
|
||||
Ecma119Node *child = dir->info.dir.children[i];
|
||||
for (i = 0; i < dir->info.dir->nchildren; i++) {
|
||||
Ecma119Node *child = dir->info.dir->children[i];
|
||||
if (child->type == ECMA119_DIR) {
|
||||
size += calc_path_table_size(child);
|
||||
}
|
||||
@ -240,8 +240,8 @@ void write_one_dir_record(Ecma119Image *t, Ecma119Node *node, int file_id,
|
||||
|
||||
if (node->type == ECMA119_DIR) {
|
||||
/* use the cached length */
|
||||
len = node->info.dir.len;
|
||||
block = node->info.dir.block;
|
||||
len = node->info.dir->len;
|
||||
block = node->info.dir->block;
|
||||
} else if (node->type == ECMA119_FILE) {
|
||||
len = iso_file_src_get_size(node->info.file);
|
||||
block = node->info.file->block;
|
||||
@ -389,7 +389,7 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir)
|
||||
memset(&info, 0, sizeof(struct susp_info));
|
||||
if (t->rockridge) {
|
||||
/* initialize the ce_block, it might be needed */
|
||||
info.ce_block = dir->info.dir.block + div_up(dir->info.dir.len,
|
||||
info.ce_block = dir->info.dir->block + div_up(dir->info.dir->len,
|
||||
BLOCK_SIZE);
|
||||
}
|
||||
|
||||
@ -414,8 +414,8 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir)
|
||||
write_one_dir_record(t, dir, 1, buf, 1, &info);
|
||||
buf += len;
|
||||
|
||||
for (i = 0; i < dir->info.dir.nchildren; i++) {
|
||||
Ecma119Node *child = dir->info.dir.children[i];
|
||||
for (i = 0; i < dir->info.dir->nchildren; i++) {
|
||||
Ecma119Node *child = dir->info.dir->children[i];
|
||||
|
||||
/* compute len of directory entry */
|
||||
fi_len = strlen(child->iso_name);
|
||||
@ -474,8 +474,8 @@ int write_dirs(Ecma119Image *t, Ecma119Node *root)
|
||||
}
|
||||
|
||||
/* recurse */
|
||||
for (i = 0; i < root->info.dir.nchildren; i++) {
|
||||
Ecma119Node *child = root->info.dir.children[i];
|
||||
for (i = 0; i < root->info.dir->nchildren; i++) {
|
||||
Ecma119Node *child = root->info.dir->children[i];
|
||||
if (child->type == ECMA119_DIR) {
|
||||
ret = write_dirs(t, child);
|
||||
if (ret < 0) {
|
||||
@ -514,7 +514,7 @@ int write_path_table(Ecma119Image *t, Ecma119Node **pathlist, int l_type)
|
||||
rec = (struct ecma119_path_table_record*) buf;
|
||||
rec->len_di[0] = dir->parent ? (uint8_t) strlen(dir->iso_name) : 1;
|
||||
rec->len_xa[0] = 0;
|
||||
write_int(rec->block, dir->info.dir.block, 4);
|
||||
write_int(rec->block, dir->info.dir->block, 4);
|
||||
write_int(rec->parent, parent + 1, 2);
|
||||
if (dir->parent) {
|
||||
memcpy(rec->dir_id, dir->iso_name, rec->len_di[0]);
|
||||
@ -558,8 +558,8 @@ int write_path_tables(Ecma119Image *t)
|
||||
|
||||
for (i = 0; i < t->ndirs; i++) {
|
||||
Ecma119Node *dir = pathlist[i];
|
||||
for (j = 0; j < dir->info.dir.nchildren; j++) {
|
||||
Ecma119Node *child = dir->info.dir.children[j];
|
||||
for (j = 0; j < dir->info.dir->nchildren; j++) {
|
||||
Ecma119Node *child = dir->info.dir->children[j];
|
||||
if (child->type == ECMA119_DIR) {
|
||||
pathlist[cur++] = child;
|
||||
}
|
||||
|
@ -96,20 +96,29 @@ int create_dir(Ecma119Image *img, IsoDir *iso, Ecma119Node **node)
|
||||
{
|
||||
int ret;
|
||||
Ecma119Node **children;
|
||||
struct ecma119_dir_info *dir_info;
|
||||
|
||||
children = calloc(1, sizeof(void*) * iso->nchildren);
|
||||
if (children == NULL) {
|
||||
return ISO_MEM_ERROR;
|
||||
}
|
||||
|
||||
dir_info = calloc(1, sizeof(struct ecma119_dir_info));
|
||||
if (dir_info == NULL) {
|
||||
free(children);
|
||||
return ISO_MEM_ERROR;
|
||||
}
|
||||
|
||||
ret = create_ecma119_node(img, (IsoNode*)iso, node);
|
||||
if (ret < 0) {
|
||||
free(children);
|
||||
free(dir_info);
|
||||
return ret;
|
||||
}
|
||||
(*node)->type = ECMA119_DIR;
|
||||
(*node)->info.dir.nchildren = 0;
|
||||
(*node)->info.dir.children = children;
|
||||
(*node)->info.dir = dir_info;
|
||||
(*node)->info.dir->nchildren = 0;
|
||||
(*node)->info.dir->children = children;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
@ -191,10 +200,11 @@ void ecma119_node_free(Ecma119Node *node)
|
||||
}
|
||||
if (node->type == ECMA119_DIR) {
|
||||
int i;
|
||||
for (i = 0; i < node->info.dir.nchildren; i++) {
|
||||
ecma119_node_free(node->info.dir.children[i]);
|
||||
for (i = 0; i < node->info.dir->nchildren; i++) {
|
||||
ecma119_node_free(node->info.dir->children[i]);
|
||||
}
|
||||
free(node->info.dir.children);
|
||||
free(node->info.dir->children);
|
||||
free(node->info.dir);
|
||||
}
|
||||
free(node->iso_name);
|
||||
iso_node_unref(node->node);
|
||||
@ -288,8 +298,8 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
|
||||
break;
|
||||
} else if (cret == ISO_SUCCESS) {
|
||||
/* add child to this node */
|
||||
int nchildren = node->info.dir.nchildren++;
|
||||
node->info.dir.children[nchildren] = child;
|
||||
int nchildren = node->info.dir->nchildren++;
|
||||
node->info.dir->children[nchildren] = child;
|
||||
child->parent = node;
|
||||
}
|
||||
pos = pos->next;
|
||||
@ -329,11 +339,11 @@ void sort_tree(Ecma119Node *root)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
qsort(root->info.dir.children, root->info.dir.nchildren, sizeof(void*),
|
||||
qsort(root->info.dir->children, root->info.dir->nchildren, sizeof(void*),
|
||||
cmp_node_name);
|
||||
for (i = 0; i < root->info.dir.nchildren; i++) {
|
||||
if (root->info.dir.children[i]->type == ECMA119_DIR)
|
||||
sort_tree(root->info.dir.children[i]);
|
||||
for (i = 0; i < root->info.dir->nchildren; i++) {
|
||||
if (root->info.dir->children[i]->type == ECMA119_DIR)
|
||||
sort_tree(root->info.dir->children[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -341,8 +351,8 @@ static
|
||||
int contains_name(Ecma119Node *dir, const char *name)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < dir->info.dir.nchildren; i++) {
|
||||
Ecma119Node *child = dir->info.dir.children[i];
|
||||
for (i = 0; i < dir->info.dir->nchildren; i++) {
|
||||
Ecma119Node *child = dir->info.dir->children[i];
|
||||
if (!strcmp(child->iso_name, name)) {
|
||||
return 1;
|
||||
}
|
||||
@ -365,8 +375,8 @@ int mangle_single_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len,
|
||||
Ecma119Node **children;
|
||||
int need_sort = 0;
|
||||
|
||||
nchildren = dir->info.dir.nchildren;
|
||||
children = dir->info.dir.children;
|
||||
nchildren = dir->info.dir->nchildren;
|
||||
children = dir->info.dir->children;
|
||||
|
||||
for (i = 0; i < nchildren; ++i) {
|
||||
char *name, *ext;
|
||||
@ -534,9 +544,9 @@ int mangle_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len,
|
||||
}
|
||||
|
||||
/* recurse */
|
||||
for (i = 0; i < dir->info.dir.nchildren; ++i) {
|
||||
if (dir->info.dir.children[i]->type == ECMA119_DIR) {
|
||||
ret = mangle_dir(img, dir->info.dir.children[i], max_file_len,
|
||||
for (i = 0; i < dir->info.dir->nchildren; ++i) {
|
||||
if (dir->info.dir->children[i]->type == ECMA119_DIR) {
|
||||
ret = mangle_dir(img, dir->info.dir->children[i], max_file_len,
|
||||
max_dir_len);
|
||||
if (ret < 0) {
|
||||
/* error */
|
||||
@ -611,8 +621,8 @@ static
|
||||
size_t max_child_name_len(Ecma119Node *dir)
|
||||
{
|
||||
size_t ret = 0, i;
|
||||
for (i = 0; i < dir->info.dir.nchildren; i++) {
|
||||
size_t len = strlen(dir->info.dir.children[i]->iso_name);
|
||||
for (i = 0; i < dir->info.dir->nchildren; i++) {
|
||||
size_t len = strlen(dir->info.dir->children[i]->iso_name);
|
||||
ret = MAX(ret, len);
|
||||
}
|
||||
return ret;
|
||||
@ -632,31 +642,31 @@ int reparent(Ecma119Node *child, Ecma119Node *parent)
|
||||
Ecma119Node *placeholder;
|
||||
|
||||
/* replace the child in the original parent with a placeholder */
|
||||
for (i = 0; i < child->parent->info.dir.nchildren; i++) {
|
||||
if (child->parent->info.dir.children[i] == child) {
|
||||
for (i = 0; i < child->parent->info.dir->nchildren; i++) {
|
||||
if (child->parent->info.dir->children[i] == child) {
|
||||
ret = create_placeholder(child->parent, child, &placeholder);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
child->parent->info.dir.children[i] = placeholder;
|
||||
child->parent->info.dir->children[i] = placeholder;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* just for debug, this should never happen... */
|
||||
if (i == child->parent->info.dir.nchildren) {
|
||||
if (i == child->parent->info.dir->nchildren) {
|
||||
return ISO_ERROR;
|
||||
}
|
||||
|
||||
/* keep track of the real parent */
|
||||
child->info.dir.real_parent = child->parent;
|
||||
child->info.dir->real_parent = child->parent;
|
||||
|
||||
/* add the child to its new parent */
|
||||
child->parent = parent;
|
||||
parent->info.dir.nchildren++;
|
||||
parent->info.dir.children = realloc(parent->info.dir.children,
|
||||
sizeof(void*) * parent->info.dir.nchildren);
|
||||
parent->info.dir.children[parent->info.dir.nchildren - 1] = child;
|
||||
parent->info.dir->nchildren++;
|
||||
parent->info.dir->children = realloc(parent->info.dir->children,
|
||||
sizeof(void*) * parent->info.dir->nchildren);
|
||||
parent->info.dir->children[parent->info.dir->nchildren - 1] = child;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
@ -696,8 +706,8 @@ int reorder_tree(Ecma119Image *img, Ecma119Node *dir, int level, int pathlen)
|
||||
} else {
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < dir->info.dir.nchildren; i++) {
|
||||
Ecma119Node *child = dir->info.dir.children[i];
|
||||
for (i = 0; i < dir->info.dir->nchildren; i++) {
|
||||
Ecma119Node *child = dir->info.dir->children[i];
|
||||
if (child->type == ECMA119_DIR) {
|
||||
int newpathlen = pathlen + 1 + strlen(child->iso_name);
|
||||
ret = reorder_tree(img, child, level + 1, newpathlen);
|
||||
|
@ -71,9 +71,7 @@ struct ecma119_node
|
||||
union
|
||||
{
|
||||
IsoFileSrc *file;
|
||||
// TODO this wastes too much memory, as dirs have much more
|
||||
// atts than other kind of files. Replace with a pointer.
|
||||
struct ecma119_dir_info dir;
|
||||
struct ecma119_dir_info *dir;
|
||||
/** this field points to the relocated directory. */
|
||||
Ecma119Node *real_me;
|
||||
} info;
|
||||
|
@ -143,7 +143,7 @@ int rrip_add_PL(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp)
|
||||
{
|
||||
uint8_t *PL;
|
||||
|
||||
if (n->type != ECMA119_DIR || n->info.dir.real_parent == NULL) {
|
||||
if (n->type != ECMA119_DIR || n->info.dir->real_parent == NULL) {
|
||||
/* should never occur */
|
||||
return ISO_ERROR;
|
||||
}
|
||||
@ -159,7 +159,7 @@ int rrip_add_PL(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp)
|
||||
PL[3] = 1;
|
||||
|
||||
/* write the location of the real parent, already computed */
|
||||
iso_bb(&PL[4], n->info.dir.real_parent->info.dir.block, 4);
|
||||
iso_bb(&PL[4], n->info.dir->real_parent->info.dir->block, 4);
|
||||
return susp_append(t, susp, PL);
|
||||
}
|
||||
|
||||
@ -243,7 +243,7 @@ int rrip_add_CL(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp)
|
||||
CL[1] = 'L';
|
||||
CL[2] = 12;
|
||||
CL[3] = 1;
|
||||
iso_bb(&CL[4], n->info.real_me->info.dir.block, 4);
|
||||
iso_bb(&CL[4], n->info.real_me->info.dir->block, 4);
|
||||
return susp_append(t, susp, CL);
|
||||
}
|
||||
|
||||
@ -547,7 +547,7 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t space,
|
||||
su_size = 44 + 26;
|
||||
|
||||
if (n->type == ECMA119_DIR) {
|
||||
if (n->info.dir.real_parent != NULL) {
|
||||
if (n->info.dir->real_parent != NULL) {
|
||||
/* it is a reallocated entry */
|
||||
if (type == 2) {
|
||||
/* we need to add a PL entry */
|
||||
@ -798,7 +798,7 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
||||
}
|
||||
|
||||
if (n->type == ECMA119_DIR) {
|
||||
if (n->info.dir.real_parent != NULL) {
|
||||
if (n->info.dir->real_parent != NULL) {
|
||||
/* it is a reallocated entry */
|
||||
if (type == 2) {
|
||||
/*
|
||||
|
@ -97,6 +97,13 @@ int mfs_stat(IsoFileSource *src, struct stat *info)
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
int mfs_access(IsoFileSource *src)
|
||||
{
|
||||
// TODO not implemented
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
int mfs_open(IsoFileSource *src)
|
||||
{
|
||||
@ -176,6 +183,7 @@ IsoFileSourceIface mfs_class = {
|
||||
mfs_get_name,
|
||||
mfs_lstat,
|
||||
mfs_stat,
|
||||
mfs_access,
|
||||
mfs_open,
|
||||
mfs_close,
|
||||
mfs_read,
|
||||
|
Loading…
Reference in New Issue
Block a user