From: ticktock35 Date: Mon, 15 Dec 2008 04:19:35 +0000 (+0000) Subject: opkg: apply "1-pkg-parse--Optimize-inefficient-parsing.patch" from OpenEmbedded X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=3cc2f7cb4d7697df61e6212bbd658f186cdf2b34;p=oweals%2Fopkg-lede.git opkg: apply "1-pkg-parse--Optimize-inefficient-parsing.patch" from OpenEmbedded pkg_parse: Optimize inefficient parsing. Instead of expensively probing all fields in row, dispatch based on the first letter of the field. Tests show ~12 times reduction in number of calls to low-level parsing functions. git-svn-id: http://opkg.googlecode.com/svn/trunk@17 e8e0d7a0-c8d9-11dd-a880-a1081c7ac358 --- diff --git a/pkg_parse.c b/pkg_parse.c index 3e6d8b4..da245cc 100644 --- a/pkg_parse.c +++ b/pkg_parse.c @@ -241,87 +241,116 @@ int pkg_parse_raw(pkg_t *pkg, char ***raw, pkg_src_t *src, pkg_dest_t *dest) for (lines = *raw; *lines; lines++) { /* fprintf(stderr, "PARSING %s\n", *lines);*/ - if(isGenericFieldType("Package:", *lines)) - pkg->name = parseGenericFieldType("Package", *lines); - else if(isGenericFieldType("Architecture:", *lines)) - pkg->architecture = parseGenericFieldType("Architecture", *lines); - else if(isGenericFieldType("Filename:", *lines)) - pkg->filename = parseGenericFieldType("Filename", *lines); - else if(isGenericFieldType("Section:", *lines)) - pkg->section = parseGenericFieldType("Section", *lines); - else if(isGenericFieldType("MD5sum:", *lines)) - pkg->md5sum = parseGenericFieldType("MD5sum", *lines); - /* The old opkg wrote out status files with the wrong case for MD5sum, - let's parse it either way */ - else if(isGenericFieldType("MD5Sum:", *lines)) - pkg->md5sum = parseGenericFieldType("MD5Sum", *lines); - else if(isGenericFieldType("Size:", *lines)) - pkg->size = parseGenericFieldType("Size", *lines); - else if(isGenericFieldType("Source:", *lines)) - pkg->source = parseGenericFieldType("Source", *lines); - else if(isGenericFieldType("Installed-Size:", *lines)) - pkg->installed_size = parseGenericFieldType("Installed-Size", *lines); - else if(isGenericFieldType("Installed-Time:", *lines)) { - char *time_str = parseGenericFieldType("Installed-Time", *lines); - pkg->installed_time = strtoul(time_str, NULL, 0); - } else if(isGenericFieldType("Priority:", *lines)) - pkg->priority = parseGenericFieldType("Priority", *lines); - else if(isGenericFieldType("Essential:", *lines)) { - char *essential_value; - essential_value = parseGenericFieldType("Essential", *lines); - if (strcmp(essential_value, "yes") == 0) { - pkg->essential = 1; - } - free(essential_value); - } - else if(isGenericFieldType("Status", *lines)) - parseStatus(pkg, *lines); - else if(isGenericFieldType("Version", *lines)) - parseVersion(pkg, *lines); - else if(isGenericFieldType("Maintainer", *lines)) - pkg->maintainer = parseGenericFieldType("Maintainer", *lines); - else if(isGenericFieldType("Conffiles", *lines)){ - parseConffiles(pkg, *lines); - reading_conffiles = 1; - } - else if(isGenericFieldType("Description", *lines)) { - pkg->description = parseGenericFieldType("Description", *lines); - reading_conffiles = 0; - reading_description = 1; - } - - else if(isGenericFieldType("Provides", *lines)){ + switch (**lines) { + case 'P': + if(isGenericFieldType("Package:", *lines)) + pkg->name = parseGenericFieldType("Package", *lines); + else if(isGenericFieldType("Priority:", *lines)) + pkg->priority = parseGenericFieldType("Priority", *lines); + else if(isGenericFieldType("Provides", *lines)){ /* Here we add the internal_use to align the off by one problem between provides_str and provides */ - provide = (char * ) malloc(strlen(*lines)+ 35 ); /* Preparing the space for the new opkg_internal_use_only */ - if ( alterProvidesLine(*lines,provide) ){ - return EINVAL; - } - pkg->provides_str = parseDependsString( provide, &pkg->provides_count); + provide = (char * ) malloc(strlen(*lines)+ 35 ); /* Preparing the space for the new opkg_internal_use_only */ + if ( alterProvidesLine(*lines,provide) ){ + return EINVAL; + } + pkg->provides_str = parseDependsString( provide, &pkg->provides_count); /* Let's try to hack a bit here. The idea is that if a package has no Provides, we would add one generic, to permit the check of dependencies in alot of other places. We will remove it before writing down the status database */ - pkg_false_provides=0; - free(provide); - } - - else if(isGenericFieldType("Depends", *lines)) - pkg->depends_str = parseDependsString(*lines, &pkg->depends_count); - else if(isGenericFieldType("Pre-Depends", *lines)) - pkg->pre_depends_str = parseDependsString(*lines, &pkg->pre_depends_count); - else if(isGenericFieldType("Recommends", *lines)) - pkg->recommends_str = parseDependsString(*lines, &pkg->recommends_count); - else if(isGenericFieldType("Suggests", *lines)) - pkg->suggests_str = parseDependsString(*lines, &pkg->suggests_count); - /* Abhaya: support for conflicts */ - else if(isGenericFieldType("Conflicts", *lines)) - pkg->conflicts_str = parseDependsString(*lines, &pkg->conflicts_count); - else if(isGenericFieldType("Replaces", *lines)) - pkg->replaces_str = parseDependsString(*lines, &pkg->replaces_count); - else if(line_is_blank(*lines)) { - lines++; + pkg_false_provides=0; + free(provide); + } + else if(isGenericFieldType("Pre-Depends", *lines)) + pkg->pre_depends_str = parseDependsString(*lines, &pkg->pre_depends_count); break; - } - else if(**lines == ' '){ + + case 'A': + if(isGenericFieldType("Architecture:", *lines)) + pkg->architecture = parseGenericFieldType("Architecture", *lines); + break; + + case 'F': + if(isGenericFieldType("Filename:", *lines)) + pkg->filename = parseGenericFieldType("Filename", *lines); + break; + + case 'S': + if(isGenericFieldType("Section:", *lines)) + pkg->section = parseGenericFieldType("Section", *lines); + else if(isGenericFieldType("Size:", *lines)) + pkg->size = parseGenericFieldType("Size", *lines); + else if(isGenericFieldType("Source:", *lines)) + pkg->source = parseGenericFieldType("Source", *lines); + else if(isGenericFieldType("Status", *lines)) + parseStatus(pkg, *lines); + else if(isGenericFieldType("Suggests", *lines)) + pkg->suggests_str = parseDependsString(*lines, &pkg->suggests_count); + break; + + case 'M': + if(isGenericFieldType("MD5sum:", *lines)) + pkg->md5sum = parseGenericFieldType("MD5sum", *lines); + /* The old opkg wrote out status files with the wrong case for MD5sum, + let's parse it either way */ + else if(isGenericFieldType("MD5Sum:", *lines)) + pkg->md5sum = parseGenericFieldType("MD5Sum", *lines); + else if(isGenericFieldType("Maintainer", *lines)) + pkg->maintainer = parseGenericFieldType("Maintainer", *lines); + break; + + case 'I': + if(isGenericFieldType("Installed-Size:", *lines)) + pkg->installed_size = parseGenericFieldType("Installed-Size", *lines); + else if(isGenericFieldType("Installed-Time:", *lines)) { + char *time_str = parseGenericFieldType("Installed-Time", *lines); + pkg->installed_time = strtoul(time_str, NULL, 0); + } + break; + + case 'E': + if(isGenericFieldType("Essential:", *lines)) { + char *essential_value; + essential_value = parseGenericFieldType("Essential", *lines); + if (strcmp(essential_value, "yes") == 0) { + pkg->essential = 1; + } + free(essential_value); + } + break; + + case 'V': + if(isGenericFieldType("Version", *lines)) + parseVersion(pkg, *lines); + break; + + case 'C': + if(isGenericFieldType("Conffiles", *lines)){ + parseConffiles(pkg, *lines); + reading_conffiles = 1; + } + else if(isGenericFieldType("Conflicts", *lines)) + pkg->conflicts_str = parseDependsString(*lines, &pkg->conflicts_count); + break; + + case 'D': + if(isGenericFieldType("Description", *lines)) { + pkg->description = parseGenericFieldType("Description", *lines); + reading_conffiles = 0; + reading_description = 1; + } + else if(isGenericFieldType("Depends", *lines)) + pkg->depends_str = parseDependsString(*lines, &pkg->depends_count); + break; + + case 'R': + if(isGenericFieldType("Recommends", *lines)) + pkg->recommends_str = parseDependsString(*lines, &pkg->recommends_count); + else if(isGenericFieldType("Replaces", *lines)) + pkg->replaces_str = parseDependsString(*lines, &pkg->replaces_count); + + break; + + case ' ': if(reading_description) { /* we already know it's not blank, so the rest of description */ pkg->description = realloc(pkg->description, @@ -332,8 +361,18 @@ int pkg_parse_raw(pkg_t *pkg, char ***raw, pkg_src_t *src, pkg_dest_t *dest) } else if(reading_conffiles) parseConffiles(pkg, *lines); + + break; + + default: + if(line_is_blank(*lines)) { + lines++; + goto out; + } } } +out:; + *raw = lines; /* If the ipk has not a Provides line, we insert our false line */ if ( pkg_false_provides==1)