From d46bb6b27b05579acf5665368c111b4cc41eedcb Mon Sep 17 00:00:00 2001 From: Allan McRae Date: Wed, 18 Jul 2012 12:09:24 +1000 Subject: Split _alpm_filelist_operation function To improve conflict checking, we will need to make these functions diverge to an extent where having two separate functions will be preferable. Signed-off-by: Allan McRae Signed-off-by: Dan McGee --- lib/libalpm/conflict.c | 12 +++++----- lib/libalpm/filelist.c | 64 ++++++++++++++++++++++++++++++++++++-------------- lib/libalpm/filelist.h | 11 ++++----- 3 files changed, 57 insertions(+), 30 deletions(-) diff --git a/lib/libalpm/conflict.c b/lib/libalpm/conflict.c index dd153fed..ccfe990c 100644 --- a/lib/libalpm/conflict.c +++ b/lib/libalpm/conflict.c @@ -367,8 +367,8 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, for(j = i->next; j; j = j->next) { alpm_list_t *common_files; alpm_pkg_t *p2 = j->data; - common_files = _alpm_filelist_operation(alpm_pkg_get_files(p1), - alpm_pkg_get_files(p2), INTERSECT); + common_files = _alpm_filelist_intersection(alpm_pkg_get_files(p1), + alpm_pkg_get_files(p2)); if(common_files) { alpm_list_t *k; @@ -400,8 +400,8 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, if(dbpkg) { alpm_list_t *difference; /* older ver of package currently installed */ - difference = _alpm_filelist_operation(alpm_pkg_get_files(p1), - alpm_pkg_get_files(dbpkg), DIFFERENCE); + difference = _alpm_filelist_difference(alpm_pkg_get_files(p1), + alpm_pkg_get_files(dbpkg)); tmpfiles.count = alpm_list_count(difference); tmpfiles.files = alpm_list_to_array(difference, tmpfiles.count, sizeof(alpm_file_t)); @@ -533,7 +533,7 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, if(handle->pm_errno == ALPM_ERR_MEMORY) { FREELIST(conflicts); if(dbpkg) { - /* only freed if it was generated from filelist_operation() */ + /* only freed if it was generated from _alpm_filelist_difference() */ free(tmpfiles.files); } return NULL; @@ -541,7 +541,7 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, } } if(dbpkg) { - /* only freed if it was generated from filelist_operation() */ + /* only freed if it was generated from _alpm_filelist_difference() */ free(tmpfiles.files); } } diff --git a/lib/libalpm/filelist.c b/lib/libalpm/filelist.c index 04075a52..f6c0ed45 100644 --- a/lib/libalpm/filelist.c +++ b/lib/libalpm/filelist.c @@ -22,16 +22,12 @@ /* libalpm */ #include "filelist.h" -/* Returns a set operation on the provided two lists of files. +/* Returns the difference of the provided two lists of files. * Pre-condition: both lists are sorted! * When done, free the list but NOT the contained data. - * - * Operations: - * DIFFERENCE - a difference operation is performed. filesA - filesB. - * INTERSECT - an intersection operation is performed. filesA & filesB. */ -alpm_list_t *_alpm_filelist_operation(alpm_filelist_t *filesA, - alpm_filelist_t *filesB, enum filelist_op operation) +alpm_list_t *_alpm_filelist_difference(alpm_filelist_t *filesA, + alpm_filelist_t *filesB) { alpm_list_t *ret = NULL; size_t ctrA = 0, ctrB = 0; @@ -49,26 +45,20 @@ alpm_list_t *_alpm_filelist_operation(alpm_filelist_t *filesA, } else { int cmp = strcmp(strA, strB); if(cmp < 0) { - if(operation == DIFFERENCE) { - /* item only in filesA, qualifies as a difference */ - ret = alpm_list_add(ret, fileA); - } + /* item only in filesA, qualifies as a difference */ + ret = alpm_list_add(ret, fileA); ctrA++; } else if(cmp > 0) { ctrB++; } else { - if(operation == INTERSECT) { - /* item in both, qualifies as an intersect */ - ret = alpm_list_add(ret, fileA); - } ctrA++; ctrB++; } - } + } } - /* if doing a difference, ensure we have completely emptied pA */ - while(operation == DIFFERENCE && ctrA < filesA->count) { + /* ensure we have completely emptied pA */ + while(ctrA < filesA->count) { alpm_file_t *fileA = filesA->files + ctrA; const char *strA = fileA->name; /* skip directories */ @@ -81,6 +71,44 @@ alpm_list_t *_alpm_filelist_operation(alpm_filelist_t *filesA, return ret; } +/* Returns the intersection of the provided two lists of files. + * Pre-condition: both lists are sorted! + * When done, free the list but NOT the contained data. + */ +alpm_list_t *_alpm_filelist_intersection(alpm_filelist_t *filesA, + alpm_filelist_t *filesB) +{ + alpm_list_t *ret = NULL; + size_t ctrA = 0, ctrB = 0; + + while(ctrA < filesA->count && ctrB < filesB->count) { + alpm_file_t *fileA = filesA->files + ctrA; + alpm_file_t *fileB = filesB->files + ctrB; + const char *strA = fileA->name; + const char *strB = fileB->name; + /* skip directories, we don't care about them */ + if(strA[strlen(strA)-1] == '/') { + ctrA++; + } else if(strB[strlen(strB)-1] == '/') { + ctrB++; + } else { + int cmp = strcmp(strA, strB); + if(cmp < 0) { + ctrA++; + } else if(cmp > 0) { + ctrB++; + } else { + /* item in both, qualifies as an intersect */ + ret = alpm_list_add(ret, fileA); + ctrA++; + ctrB++; + } + } + } + + return ret; +} + /* Helper function for comparing files list entries */ int _alpm_files_cmp(const void *f1, const void *f2) diff --git a/lib/libalpm/filelist.h b/lib/libalpm/filelist.h index 991045e9..2d5cbc03 100644 --- a/lib/libalpm/filelist.h +++ b/lib/libalpm/filelist.h @@ -21,13 +21,12 @@ #include "alpm.h" -enum filelist_op { - DIFFERENCE = 0, - INTERSECT = 1 -}; -alpm_list_t *_alpm_filelist_operation(alpm_filelist_t *filesA, - alpm_filelist_t *filesB, enum filelist_op operation); +alpm_list_t *_alpm_filelist_difference(alpm_filelist_t *filesA, + alpm_filelist_t *filesB); + +alpm_list_t *_alpm_filelist_intersection(alpm_filelist_t *filesA, + alpm_filelist_t *filesB); int _alpm_files_cmp(const void *f1, const void *f2); -- cgit v1.2.3-70-g09d2