Saved more CPU cycles by optimistic adding of file objects

This commit is contained in:
Thomas Schmitt 2011-04-30 12:11:27 +00:00
parent 2fe76f0f0e
commit 686659514b
2 changed files with 265 additions and 17 deletions

View File

@ -144,7 +144,7 @@ int Xorriso_graft_split(struct XorrisO *xorriso, IsoImage *volume,
offset, xorriso->split_size, offset, xorriso->split_size,
&part_node, 8); &part_node, 8);
if(ret<=0) if(ret<=0)
return(0); return(ret);
} }
sprintf(xorriso->info_text, "Split into %d parts: %s", sprintf(xorriso->info_text, "Split into %d parts: %s",
total_parts, Text_shellsafe(nominal_target, sfe, 0)); total_parts, Text_shellsafe(nominal_target, sfe, 0));
@ -154,7 +154,9 @@ int Xorriso_graft_split(struct XorrisO *xorriso, IsoImage *volume,
/* /*
@param flag bit3= cut_out_node: offset and size are valid @param flag bit0= ISO_NODE_NAME_NOT_UNIQUE exception mode:
Do not issue message. Return existing node into *node.
bit3= cut_out_node: offset and size are valid
bit8= hide in iso_rr bit8= hide in iso_rr
bit9= hide in joliet bit9= hide in joliet
*/ */
@ -226,6 +228,9 @@ int Xorriso_tree_graft_node(struct XorrisO *xorriso, IsoImage *volume,
ex:; ex:;
if(ret<0) { if(ret<0) {
if(ret == ISO_NODE_NAME_NOT_UNIQUE && (flag & 1)) {
iso_dir_get_node(dir, img_name, node);
} else {
Xorriso_process_msg_queues(xorriso,0); Xorriso_process_msg_queues(xorriso,0);
if(ret == ISO_RR_NAME_TOO_LONG || ret == ISO_RR_NAME_RESERVED || if(ret == ISO_RR_NAME_TOO_LONG || ret == ISO_RR_NAME_RESERVED ||
ret == ISO_RR_PATH_TOO_LONG) ret == ISO_RR_PATH_TOO_LONG)
@ -234,6 +239,7 @@ ex:;
namept= nominal_source; namept= nominal_source;
Xorriso_report_iso_error(xorriso, namept, ret, Xorriso_report_iso_error(xorriso, namept, ret,
"Cannot add node to tree", 0, "FAILURE", 1|2); "Cannot add node to tree", 0, "FAILURE", 1|2);
}
return(ret); return(ret);
} }
if(LIBISO_ISREG(*node)) if(LIBISO_ISREG(*node))
@ -242,6 +248,70 @@ ex:;
} }
/*
@param boss_iter Opaque handle to be forwarded to actions in ISO image
Set to NULL if calling this function without having
a boss iterator objetc.
@param node Pointer to pointer to existing node,
*node is set to NULL, if the node gets removed.
@param flag bit0= source is directory
bit4= return 3 on rejection by exclusion or user
bit6= do not delete eventually existing node from di_array
bit7= no special handling of split file directories
@return 1= no action was needed, 2= target removed,
3= rejected with bit4, <=0 means error
*/
int Xoriso_handle_collision(struct XorrisO *xorriso, void *boss_iter,
IsoNode **node, char *img_path,
char *full_img_path, char *disk_path,
char *show_path, int flag)
{
int ret, target_is_dir, target_is_split, source_is_dir;
source_is_dir= flag & 1;
target_is_dir= LIBISO_ISDIR(*node);
target_is_split= 0;
if(target_is_dir && !(flag & 128))
target_is_split= Xorriso_is_split(xorriso, "", (void *) *node, 1 | 2);
if(!((target_is_dir && !target_is_split) && source_is_dir)) {
Xorriso_process_msg_queues(xorriso, 0);
/* handle overwrite situation */;
if(xorriso->do_overwrite == 1 ||
(xorriso->do_overwrite == 2 && !(target_is_dir && !target_is_split))) {
ret= Xorriso_rmi(xorriso, boss_iter, (off_t) 0, img_path,
1 | 8 | (flag & 64));
if(ret <= 0)
return(ret);
if(ret == 3) {
sprintf(xorriso->info_text, "User revoked adding of: ");
Text_shellsafe(show_path, xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
return(3 * !!(flag & 16));
}
*node= NULL;
return(2);
}
if (disk_path[0])
Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0);
if(strcmp(full_img_path, img_path) == 0)
sprintf(xorriso->info_text,
"While grafting '%s' : file object exists and may not be overwritten",
img_path);
else
sprintf(xorriso->info_text,
"While grafting '%s' : '%s' exists and may not be overwritten",
full_img_path, img_path);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
return(0);
}
return(1);
}
/* @param flag bit0= recursion is active /* @param flag bit0= recursion is active
bit1= do not report added files bit1= do not report added files
bit6= do not delete eventually existing node from di_array bit6= do not delete eventually existing node from di_array
@ -255,8 +325,8 @@ int Xorriso_add_tree(struct XorrisO *xorriso, IsoDir *dir,
{ {
IsoImage *volume; IsoImage *volume;
IsoNode *node; IsoNode *node;
int ret, target_is_dir, source_is_dir, source_is_link, fret, was_failure= 0; int ret, source_is_dir, source_is_link, fret, was_failure= 0;
int do_not_dive, target_is_split= 0, hide_attrs; int do_not_dive, hide_attrs;
struct DirseQ *dirseq= NULL; struct DirseQ *dirseq= NULL;
char *name, *img_name, *srcpt, *stbuf_src= ""; char *name, *img_name, *srcpt, *stbuf_src= "";
struct stat stbuf, hstbuf; struct stat stbuf, hstbuf;
@ -265,6 +335,15 @@ int Xorriso_add_tree(struct XorrisO *xorriso, IsoDir *dir,
char *sfe= NULL, *sfe2= NULL; char *sfe= NULL, *sfe2= NULL;
char *disk_path= NULL, *img_path= NULL, *link_target= NULL; char *disk_path= NULL, *img_path= NULL, *link_target= NULL;
#define Xorriso_add_handle_collisioN 1
#define Xorriso_optimistic_add_treE 1
#ifndef Xorriso_optimistic_add_treE
#ifndef Xorriso_add_handle_collisioN
int target_is_split= 0, target_is_dir;
#endif
#endif
/* Avoiding large local memory objects in order to save stack space */ /* Avoiding large local memory objects in order to save stack space */
sfe= malloc(5*SfileadrL); sfe= malloc(5*SfileadrL);
sfe2= malloc(5*SfileadrL); sfe2= malloc(5*SfileadrL);
@ -404,6 +483,28 @@ cannot_lstat:;
do_not_dive= 1; do_not_dive= 1;
} }
#ifdef Xorriso_optimistic_add_treE
ret= Xorriso_tree_graft_node(xorriso, volume, dir, srcpt, img_name,
"", img_path, (off_t) 0, (off_t) 0,
&node, 1 | (hide_attrs << 8));
if(ret == ISO_NODE_NAME_NOT_UNIQUE) {
ret= Xoriso_handle_collision(xorriso, NULL, &node, img_path, img_path,
srcpt, img_path,
(!!source_is_dir) | (flag & (64 | 128)));
if(ret <= 0)
goto was_problem;
if(node == NULL) {
ret= Xorriso_tree_graft_node(xorriso, volume, dir, srcpt, img_name,
"", img_path, (off_t) 0, (off_t) 0,
&node, (hide_attrs << 8));
if(ret <= 0)
node= NULL;
}
}
#else /* Xorriso_optimistic_add_treE */
/* does a node exist with this name ? */ /* does a node exist with this name ? */
node= NULL; node= NULL;
if(dir != NULL) { if(dir != NULL) {
@ -450,6 +551,9 @@ cannot_lstat:;
"", img_path, (off_t) 0, (off_t) 0, "", img_path, (off_t) 0, (off_t) 0,
&node, (hide_attrs << 8)); &node, (hide_attrs << 8));
} }
#endif /* Xorriso_optimistic_add_treE */
if(node==NULL) { if(node==NULL) {
Xorriso_process_msg_queues(xorriso,0); Xorriso_process_msg_queues(xorriso,0);
Xorriso_msgs_submit(xorriso, 0, stbuf_src, 0, "ERRFILE", 0); Xorriso_msgs_submit(xorriso, 0, stbuf_src, 0, "ERRFILE", 0);
@ -624,12 +728,21 @@ int Xorriso_graft_in(struct XorrisO *xorriso, void *boss_iter,
IsoImage *volume; IsoImage *volume;
char path[SfileadrL], *apt, *npt, *cpt, sfe[5*SfileadrL], sfe2[5*SfileadrL]; char path[SfileadrL], *apt, *npt, *cpt, sfe[5*SfileadrL], sfe2[5*SfileadrL];
char *disk_path_pt, resolved_disk_path[SfileadrL]; char *disk_path_pt, resolved_disk_path[SfileadrL];
IsoDir *dir, *hdir; IsoDir *dir= NULL, *hdir;
IsoNode *node; IsoNode *node;
int done= 0, is_dir= 0, l, ret, target_is_dir, source_is_dir, resolve_link= 0; int done= 0, is_dir= 0, l, ret, source_is_dir, resolve_link= 0;
int target_is_split, hide_attrs; int hide_attrs;
struct stat stbuf; struct stat stbuf;
#define Xorriso_graft_handle_collisioN 1
#define Xorriso_optimistic_graft_iN 1
#ifndef Xorriso_optimistic_graft_iN
#ifndef Xorriso_graft_handle_collisioN
int target_is_split, target_is_dir;
#endif
#endif
hide_attrs= (flag >> 8) & 3; hide_attrs= (flag >> 8) & 3;
if (disk_path == NULL && !(flag & 1)) { if (disk_path == NULL && !(flag & 1)) {
Xorriso_msgs_submit(xorriso, 0, Xorriso_msgs_submit(xorriso, 0,
@ -753,8 +866,136 @@ int Xorriso_graft_in(struct XorrisO *xorriso, void *boss_iter,
continue; continue;
} }
source_is_dir= (is_dir || (flag&1) || !done); source_is_dir= (is_dir || (flag&1) || !done);
ret= Xorriso_node_from_path(xorriso, volume, path, &node, 1);
#ifdef Xorriso_optimistic_graft_iN
/* Directories of the source path are likely to exist already as directory
in the image.
That will cause two lookups with optimistic, and only one with
pessimistic.
So optimism will pay off only with the leaf. I.e. if(done).
*/
if(source_is_dir) { /* eventually create directory */
ret= iso_dir_get_node(dir, apt, &node);
if(ret > 0) { if(ret > 0) {
ret= Xoriso_handle_collision(xorriso, boss_iter, &node, path,
img_path, disk_path,
disk_path[0] ? disk_path : img_path,
(!!source_is_dir) | (flag & (16 | 64 | 128)));
if(ret <= 0 || ret == 3)
return(ret);
if(ret == 1 && node != NULL)
dir= (IsoDir *) node;
} else
node= NULL;
if(node == NULL) {
ret= iso_tree_add_new_dir(dir, apt, &hdir);
if(ret < 0) {
Xorriso_process_msg_queues(xorriso,0);
if(disk_path[0])
Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0);
Xorriso_report_iso_error(xorriso, img_path, ret,
"Cannot create directory", 0, "FAILURE", 1);
sprintf(xorriso->info_text,
"While grafting '%s' : could not insert '%s'", img_path, path);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
return(0);
}
if(xorriso->update_flags & 1) {
ret= Xorriso_mark_update_merge(xorriso, path, (IsoNode *) hdir, 1);
if(ret <= 0)
return(0);
}
dir= hdir;
Xorriso_set_change_pending(xorriso, 0);
iso_node_set_ctime((IsoNode *) dir, time(NULL));
iso_node_set_uid((IsoNode *) dir, geteuid());
iso_node_set_gid((IsoNode *) dir, getegid());
if(disk_path[0] && !done) {
/* This not only copies disk directory properties
but also sets eventual hide_attrs */
Xorriso_copy_implicit_properties(xorriso, dir, img_path, path,
disk_path, !!(flag&8));
}
}
}
if(done) {
attach_source:;
if(flag&1) {
/* directory node was created above */;
} else if(is_dir) {
Xorriso_transfer_properties(xorriso, &stbuf, disk_path,
(IsoNode *) dir, 4 | 32);
if(!(flag&32)) {
ret= Xorriso_add_tree(xorriso, dir, img_path, disk_path, NULL,
flag & (2 | 64 | 128));
if(ret<=0)
return(ret);
}
} else {
if(resolve_link) {
ret= Xorriso_resolve_link(xorriso, disk_path, resolved_disk_path, 0);
if(ret<=0)
return(ret);
disk_path_pt= resolved_disk_path;
} else
disk_path_pt= disk_path;
ret= Xorriso_tree_graft_node(xorriso, volume, dir, disk_path_pt, apt,
disk_path, img_path, offset, cut_size,
&node, 1 | (flag & 8) | (hide_attrs << 8));
if(ret == ISO_NODE_NAME_NOT_UNIQUE) {
ret= Xoriso_handle_collision(xorriso, boss_iter, &node, img_path,
img_path, disk_path,
disk_path[0] ? disk_path : img_path,
(flag & (16 | 64 | 128)));
if(ret <= 0 || ret == 3)
return(ret);
ret= Xorriso_tree_graft_node(xorriso, volume, dir, disk_path_pt, apt,
disk_path, img_path, offset, cut_size,
&node, (flag & 8) | (hide_attrs << 8));
}
if(ret<=0) {
sprintf(xorriso->info_text, "Grafting failed: %s = %s",
Text_shellsafe(img_path,sfe,0), Text_shellsafe(disk_path,sfe2,0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
return(0);
}
Xorriso_set_change_pending(xorriso, 0);
iso_node_set_name(node, apt);
xorriso->pacifier_count++;
if(xorriso->pacifier_count%100 && !(flag&2))
Xorriso_pacifier_callback(xorriso, "files added",
xorriso->pacifier_count,
xorriso->pacifier_total, "", 0);
}
} else
*npt= '/';
#else /* Xorriso_optimistic_graft_iN */
node= NULL;
ret= iso_dir_get_node(dir, apt, &node);
if(ret>0) {
#ifdef Xorriso_graft_handle_collisioN
ret= Xoriso_handle_collision(xorriso, boss_iter, &node, path, img_path,
disk_path,
disk_path[0] ? disk_path : img_path,
(!!source_is_dir) | (flag & (16 | 64 | 128)));
if(ret <= 0 || ret == 3)
return(ret);
if(ret == 2)
goto handle_path_node;
#else /* Xorriso_graft_handle_collisioN */
target_is_dir= LIBISO_ISDIR(node); target_is_dir= LIBISO_ISDIR(node);
target_is_split= 0; target_is_split= 0;
@ -790,6 +1031,9 @@ int Xorriso_graft_in(struct XorrisO *xorriso, void *boss_iter,
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
return(0); return(0);
} }
#endif /* ! Xorriso_graft_handle_collisioN */
dir= (IsoDir *) node; dir= (IsoDir *) node;
} }
@ -868,7 +1112,11 @@ attach_source:;
} }
} else } else
*npt= '/'; *npt= '/';
#endif /* ! Xorriso_optimistic_graft_iN */
} }
Xorriso_process_msg_queues(xorriso,0); Xorriso_process_msg_queues(xorriso,0);
return(1+!!is_dir); return(1+!!is_dir);
} }

View File

@ -1 +1 @@
#define Xorriso_timestamP "2011.04.27.150829" #define Xorriso_timestamP "2011.04.30.121138"