Make files_msort available to the library as sorting a filelist will be useful for packages where the filelist changes after resolving symlinks. Signed-off-by: Allan McRae <allan@archlinux.org> --- lib/libalpm/be_package.c | 49 +----------------------------------------------- lib/libalpm/package.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++ lib/libalpm/package.h | 1 + 3 files changed, 50 insertions(+), 48 deletions(-) diff --git a/lib/libalpm/be_package.c b/lib/libalpm/be_package.c index dd027f5..ed71be2 100644 --- a/lib/libalpm/be_package.c +++ b/lib/libalpm/be_package.c @@ -248,53 +248,6 @@ static int parse_descfile(alpm_handle_t *handle, struct archive *a, alpm_pkg_t * return 0; } -static void files_merge(alpm_file_t a[], alpm_file_t b[], alpm_file_t c[], - size_t m, size_t n) -{ - size_t i = 0, j = 0, k = 0; - while(i < m && j < n) { - if(strcmp(a[i].name, b[j].name) < 0) { - c[k++] = a[i++]; - } else { - c[k++] = b[j++]; - } - } - while(i < m) { - c[k++] = a[i++]; - } - while(j < n) { - c[k++] = b[j++]; - } -} - -static alpm_file_t *files_msort(alpm_file_t *files, size_t n) -{ - alpm_file_t *work; - size_t blocksize = 1; - - CALLOC(work, n, sizeof(alpm_file_t), return NULL); - - for(blocksize = 1; blocksize < n; blocksize *= 2) { - size_t i, max_extent = 0; - for(i = 0; i < n - blocksize; i += 2 * blocksize) { - /* this limits our actual merge to the length of the array, since we will - * not likely be a perfect power of two. */ - size_t right_blocksize = blocksize; - if(i + blocksize * 2 > n) { - right_blocksize = n - i - blocksize; - } - files_merge(files + i, files + i + blocksize, work + i, - blocksize, right_blocksize); - max_extent = i + blocksize + right_blocksize; - } - /* ensure we only copy what we actually touched on this merge pass, - * no more, no less */ - memcpy(files, work, max_extent * sizeof(alpm_file_t)); - } - free(work); - return files; -} - /** * Validate a package. * @param handle the context handle @@ -536,7 +489,7 @@ alpm_pkg_t *_alpm_pkg_load_internal(alpm_handle_t *handle, /* "checking for conflicts" requires a sorted list, ensure that here */ _alpm_log(handle, ALPM_LOG_DEBUG, "sorting package filelist for %s\n", pkgfile); - newpkg->files.files = files_msort(newpkg->files.files, + newpkg->files.files = _alpm_files_msort(newpkg->files.files, newpkg->files.count); } newpkg->infolevel |= INFRQ_FILES; diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c index 46d1473..8a7b01f 100644 --- a/lib/libalpm/package.c +++ b/lib/libalpm/package.c @@ -459,6 +459,54 @@ int _alpm_files_cmp(const void *f1, const void *f2) return strcmp(file1->name, file2->name); } + +static void files_merge(alpm_file_t a[], alpm_file_t b[], alpm_file_t c[], + size_t m, size_t n) +{ + size_t i = 0, j = 0, k = 0; + while(i < m && j < n) { + if(strcmp(a[i].name, b[j].name) < 0) { + c[k++] = a[i++]; + } else { + c[k++] = b[j++]; + } + } + while(i < m) { + c[k++] = a[i++]; + } + while(j < n) { + c[k++] = b[j++]; + } +} + +alpm_file_t *_alpm_files_msort(alpm_file_t *files, size_t n) +{ + alpm_file_t *work; + size_t blocksize = 1; + + CALLOC(work, n, sizeof(alpm_file_t), return NULL); + + for(blocksize = 1; blocksize < n; blocksize *= 2) { + size_t i, max_extent = 0; + for(i = 0; i < n - blocksize; i += 2 * blocksize) { + /* this limits our actual merge to the length of the array, since we will + * not likely be a perfect power of two. */ + size_t right_blocksize = blocksize; + if(i + blocksize * 2 > n) { + right_blocksize = n - i - blocksize; + } + files_merge(files + i, files + i + blocksize, work + i, + blocksize, right_blocksize); + max_extent = i + blocksize + right_blocksize; + } + /* ensure we only copy what we actually touched on this merge pass, + * no more, no less */ + memcpy(files, work, max_extent * sizeof(alpm_file_t)); + } + free(work); + return files; +} + alpm_pkg_t *_alpm_pkg_new(void) { alpm_pkg_t *pkg; diff --git a/lib/libalpm/package.h b/lib/libalpm/package.h index c473549..3c539ef 100644 --- a/lib/libalpm/package.h +++ b/lib/libalpm/package.h @@ -127,6 +127,7 @@ struct __alpm_pkg_t { alpm_file_t *_alpm_file_copy(alpm_file_t *dest, const alpm_file_t *src); int _alpm_files_cmp(const void *f1, const void *f2); +alpm_file_t *_alpm_files_msort(alpm_file_t *files, size_t n); alpm_pkg_t *_alpm_pkg_new(void); int _alpm_pkg_dup(alpm_pkg_t *pkg, alpm_pkg_t **new_ptr); -- 1.7.11.2