diff --git a/Makefile.in b/Makefile.in index 1981dbe..4c4adac 100644 --- a/Makefile.in +++ b/Makefile.in @@ -223,7 +223,7 @@ BASE_CPPFLAGS = -I. -I./lzma -I./lzfx -I./lz4 -I./rabin -I./bsdiff -DNODEFAULT_P -I./crypto/xsalsa20 -I./archive -pedantic -Wall -I./filters -fno-strict-aliasing \ -Wno-unused-but-set-variable -Wno-enum-compare \ @COMPAT_CPPFLAGS@ @XSALSA20_DEBUG@ @LIBARCHIVE_INC@ -I./filters/packjpg -COMMON_CPPFLAGS = $(BASE_CPPFLAGS) -std=gnu99 +COMMON_CPPFLAGS = $(BASE_CPPFLAGS) -std=gnu99 COMMON_CPPFLAGS_cpp = $(BASE_CPPFLAGS) COMMON_VEC_FLAGS = -ftree-vectorize COMMON_LOOP_OPTFLAGS = $(VEC_FLAGS) -floop-interchange -floop-block diff --git a/archive/pc_arc_filter.c b/archive/pc_arc_filter.c index d0f6aa0..bef96b2 100644 --- a/archive/pc_arc_filter.c +++ b/archive/pc_arc_filter.c @@ -20,7 +20,7 @@ * If not, see . * * moinakg@belenix.org, http://moinakg.wordpress.com/ - * + * */ /* @@ -42,23 +42,28 @@ #include "pc_arc_filter.h" #include "pc_archive.h" -#define PACKJPG_DEF_BUFSIZ (512 * 1024) -#define JPG_SIZE_LIMIT (8 * 1024 * 1024) -#define PJG_APPVERSION1 (25) -#define PJG_APPVERSION2 (25) +#ifndef _MPLV2_LICENSE_ +# define PACKJPG_DEF_BUFSIZ (512 * 1024) +# define JPG_SIZE_LIMIT (8 * 1024 * 1024) +# define PJG_APPVERSION1 (25) +# define PJG_APPVERSION2 (25) +#endif struct scratch_buffer { uchar_t *in_buff; size_t in_bufflen; }; +#ifndef _MPLV2_LICENSE_ extern size_t packjpg_filter_process(uchar_t *in_buf, size_t len, uchar_t **out_buf); ssize_t packjpg_filter(struct filter_info *fi, void *filter_private); +#endif void add_filters_by_type(struct type_data *typetab, struct filter_flags *ff) { +#ifndef _MPLV2_LICENSE_ struct scratch_buffer *sdat; int slot; @@ -72,6 +77,7 @@ add_filters_by_type(struct type_data *typetab, struct filter_flags *ff) typetab[slot].filter_func = packjpg_filter; typetab[slot].filter_name = "packJPG"; } +#endif } static void @@ -138,6 +144,7 @@ write_archive_data(struct archive *aw, uchar_t *out_buf, size_t len, int block_s return (tot); } +#ifndef _MPLV2_LICENSE_ int pjg_version_supported(char ver) { @@ -252,4 +259,5 @@ packjpg_filter(struct filter_info *fi, void *filter_private) free(out); return (rv); } +#endif diff --git a/archive/pc_arc_filter.h b/archive/pc_arc_filter.h index 211d087..d7ab33f 100644 --- a/archive/pc_arc_filter.h +++ b/archive/pc_arc_filter.h @@ -20,7 +20,7 @@ * If not, see . * * moinakg@belenix.org, http://moinakg.wordpress.com/ - * + * */ #ifndef _PC_ARCHIVE_FILTER_H @@ -67,4 +67,4 @@ void add_filters_by_type(struct type_data *typetab, struct filter_flags *ff); } #endif -#endif +#endif diff --git a/archive/pc_archive.c b/archive/pc_archive.c index 8ea1803..9226c46 100644 --- a/archive/pc_archive.c +++ b/archive/pc_archive.c @@ -20,7 +20,7 @@ * If not, see . * * moinakg@belenix.org, http://moinakg.wordpress.com/ - * + * */ /* diff --git a/archive/pjpg_helper.cpp b/archive/pjpg_helper.cpp index b82c32d..ab25f72 100644 --- a/archive/pjpg_helper.cpp +++ b/archive/pjpg_helper.cpp @@ -20,7 +20,7 @@ * If not, see . * * moinakg@belenix.org, http://moinakg.wordpress.com/ - * + * */ /* @@ -32,6 +32,8 @@ #include #include #include + +#ifndef _MPLV2_LICENSE_ #include #ifdef __cplusplus @@ -104,3 +106,4 @@ packjpg_filter_process(uchar_t *in_buf, size_t len, uchar_t **out_buf) #ifdef __cplusplus } #endif +#endif diff --git a/config b/config index de7434c..08697e1 100755 --- a/config +++ b/config @@ -20,6 +20,8 @@ # moinakg@belenix.org, http://moinakg.wordpress.com/ # +my_license=LGPLv3 + usage() { prog=$1 cat << _EOF @@ -40,9 +42,12 @@ ${prog} [] Enable building against an alternate Bzip2 and library installation. --with-libarchive= (Default: System) Enable building against an alternate libarchive installation. +--with-external-libbsc= + Enable building with exernal libbsc sources. Can be used to link with + ASLv2 libbsc when using MPLv2 licensed sources. --no-sse-detect Do NOT attempt to probe the system's SSE capability for build flags. Implies '--no-avx-detect' below. ---no-avx-detect Do NOT attempt to probe the system's AVX apability for build flags. +--no-avx-detect Do NOT attempt to probe the system's AVX capability for build flags. --no-1.3-archive-compat Disable compatibility with compressed archives created with Pcompress version 1.3 (default: retain compatibility). Hash formats changed from version 1.3 to 1.4 so this option is required if files created using @@ -60,12 +65,16 @@ debug=0 allocator=1 debug_stats=0 prefix=/usr -libbsc_dir=./bsc -libbsc_lib=${libbsc_dir}/libbsc.a -libbsclflags='\$\(LIBBSCLFLAGS\)' -libbscwrapobj='\$\(LIBBSCWRAPOBJ\)' -libbscgenopt='\$\(LIBBSCGEN_OPT\)' -libbsccppflags='\$\(LIBBSCCPPFLAGS\)' + +if [ "$my_license" = "LGPLv3" ] +then + libbsc_dir=./bsc + libbsc_lib=${libbsc_dir}/libbsc.a + libbsclflags='\$\(LIBBSCLFLAGS\)' + libbscwrapobj='\$\(LIBBSCWRAPOBJ\)' + libbscgenopt='\$\(LIBBSCGEN_OPT\)' + libbsccppflags='\$\(LIBBSCCPPFLAGS\)' +fi openssl_prefix= openssl_libdir= openssl_incdir= @@ -195,6 +204,14 @@ do --with-libarchive=*) libarchive_prefix=`echo ${arg1} | cut -f2 -d"="` ;; + --with-external-libbsc) + libbsc_dir=`echo ${arg1} | cut -f2 -d"="` + libbsc_lib=${libbsc_dir}/libbsc.a + libbsclflags='\$\(LIBBSCLFLAGS\)' + libbscwrapobj='\$\(LIBBSCWRAPOBJ\)' + libbscgenopt='\$\(LIBBSCGEN_OPT\)' + libbsccppflags='\$\(LIBBSCCPPFLAGS\)' + ;; --use-key256) keylen='-DDEFAULT_KEYLEN=16' ;; diff --git a/filters/lzp/lzp.c b/filters/lzp/lzp.c index 706a20a..06dffbd 100644 --- a/filters/lzp/lzp.c +++ b/filters/lzp/lzp.c @@ -20,7 +20,7 @@ * If not, see . * * moinakg@belenix.org, http://moinakg.wordpress.com/ - * + * */ /*-----------------------------------------------------------*/ diff --git a/libbsc_compress.c b/libbsc_compress.c index 21fed2f..9658924 100644 --- a/libbsc_compress.c +++ b/libbsc_compress.c @@ -20,7 +20,7 @@ * If not, see . * * moinakg@belenix.org, http://moinakg.wordpress.com/ - * + * */ #include @@ -150,7 +150,7 @@ int libbsc_deinit(void **data) { struct libbsc_params *bscdat = (struct libbsc_params *)(*data); - + if (bscdat) { slab_free(NULL, bscdat); } diff --git a/pcompress.c b/pcompress.c index 8553608..c21b9f5 100644 --- a/pcompress.c +++ b/pcompress.c @@ -78,7 +78,8 @@ usage(pc_ctx_t *pctx) { fprintf(stderr, -"\nPcompress Version %s\n\n" +"\nPcompress Version %s\n" +"License: %s\n\n" "See README.md for detailed usage.\n\n" "Standard Usage\n" "==============\n" @@ -144,7 +145,7 @@ usage(pc_ctx_t *pctx) " Default output name if omitted: .out\n\n" " If Archiving was done then this should be the name of a directory into which\n" " extracted files are restored. Default if omitted: Current directory.\n\n", - UTILITY_VERSION, pctx->exec_name, pctx->exec_name, pctx->exec_name); + UTILITY_VERSION, LICENSE_STRING, pctx->exec_name, pctx->exec_name, pctx->exec_name); fprintf(stderr, " Encryption\n" " ----------\n" @@ -187,10 +188,10 @@ show_compression_stats(pc_ctx_t *pctx) /* * Wrapper functions to pre-process the buffer and then call the main compression routine. * At present only LZP pre-compression is used below. Some extra metadata is added: - * + * * Byte 0: A flag to indicate which pre-processor was used. * Byte 1 - Byte 8: Size of buffer after pre-processing - * + * * It is possible for a buffer to be only pre-processed and not compressed by the final * algorithm if the final one fails to compress for some reason. However the vice versa * is not allowed. @@ -234,6 +235,7 @@ preproc_compress(pc_ctx_t *pctx, compress_func_ptr cmp_func, void *src, uint64_t } } +#ifndef _MPLV2_LICENSE_ if (pctx->lzp_preprocess && stype != TYPE_BMP && stype != TYPE_TIFF) { int hashsize; @@ -249,6 +251,7 @@ preproc_compress(pc_ctx_t *pctx, compress_func_ptr cmp_func, void *src, uint64_t type |= PREPROC_TYPE_LZP; } } +#endif if (pctx->enable_delta2_encode && props->delta2_span > 0 && stype != TYPE_DNA_SEQ && stype != TYPE_BMP && @@ -349,6 +352,7 @@ preproc_decompress(pc_ctx_t *pctx, compress_func_ptr dec_func, void *src, uint64 } if (type & PREPROC_TYPE_LZP) { +#ifndef _MPLV2_LICENSE_ int hashsize; hashsize = lzp_hash_size(level); result = lzp_decompress((const uchar_t *)src, (uchar_t *)dst, srclen, @@ -362,6 +366,10 @@ preproc_decompress(pc_ctx_t *pctx, compress_func_ptr dec_func, void *src, uint64 log_msg(LOG_ERR, 0, "LZP decompression failed."); return (result); } +#else + log_msg(LOG_ERR, 0, "LZP feature not available in this build (MPLv2). Aborting."); + return (-1); +#endif } if (type & PREPROC_TYPE_DISPACK) { @@ -2960,10 +2968,12 @@ init_pc_context(pc_ctx_t *pctx, int argc, char *argv[]) pctx->enable_rabin_split = 0; break; +#ifndef _MPLV2_LICENSE_ case 'L': pctx->advanced_opts = 1; pctx->lzp_preprocess = 1; break; +#endif case 'P': pctx->advanced_opts = 1; diff --git a/pcompress.h b/pcompress.h index fcac6fc..601f5b3 100644 --- a/pcompress.h +++ b/pcompress.h @@ -20,7 +20,7 @@ * If not, see . * * moinakg@belenix.org, http://moinakg.wordpress.com/ - * + * */ #ifndef _PCOMPRESS_H @@ -49,6 +49,12 @@ extern "C" { #define MASK_CRYPTO_ALG 0x30 #define MAX_LEVEL 14 +#ifndef _MPLV2_LICENSE_ +#define LICENSE_STRING "LGPLv3" +#else +#define LICENSE_STRING "MPLv2" +#endif + #define COMPRESSED 1 #define UNCOMPRESSED 0 #define CHSIZE_MASK 0x80 diff --git a/rabin/global/index.c b/rabin/global/index.c index 3e7b926..64f8d0b 100644 --- a/rabin/global/index.c +++ b/rabin/global/index.c @@ -76,9 +76,12 @@ init_global_db(char *configfile) int init_on_disk_index(archive_config_t *cfg) { +#if 0 if (file_exists()) { } +#endif + return (0); } void diff --git a/rabin/rabin_dedup.c b/rabin/rabin_dedup.c index ec8b775..6979cf5 100755 --- a/rabin/rabin_dedup.c +++ b/rabin/rabin_dedup.c @@ -1,27 +1,27 @@ /* * The rabin polynomial computation is derived from: * http://code.google.com/p/rabin-fingerprint-c/ - * + * * originally created by Joel Lawrence Tucci on 09-March-2011. - * + * * Rabin polynomial portions Copyright (c) 2011 Joel Lawrence Tucci * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: - * + * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. - * + * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * + * * Neither the name of the project's author nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS @@ -58,7 +58,7 @@ * If not, see . * * moinakg@belenix.org, http://moinakg.wordpress.com/ - * + * */ #ifndef __STDC_FORMAT_MACROS @@ -75,6 +75,9 @@ #include #include #include + +#define QSORT_LT(a, b) ((*a)<(*b)) +#define QSORT_TYPE uint64_t #include #include "rabin_dedup.h" @@ -445,11 +448,10 @@ isort_uint64(uint64_t *ary, uint32_t nitems) * Sort an array of 64-bit unsigned integers. The QSORT macro provides an * inline quicksort routine that does not use a callback function. */ -#define int_lt(a,b) ((*a)<(*b)) static void do_qsort(uint64_t *arr, uint32_t len) { - QSORT(uint64_t, arr, len, int_lt); + QSORT(arr, len); } static inline int diff --git a/utils/qsort.h b/utils/qsort.h index 30d55ba..4097f02 100644 --- a/utils/qsort.h +++ b/utils/qsort.h @@ -22,293 +22,8 @@ * moinakg@belenix.org, http://moinakg.wordpress.com/ */ -/* $Id: qsort.h,v 1.5 2008-01-28 18:16:49 mjt Exp $ - * Adopted from GNU glibc by Mjt. - * See stdlib/qsort.c in glibc */ - -/* Copyright (C) 1991, 1992, 1996, 1997, 1999 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Written by Douglas C. Schmidt (schmidt@ics.uci.edu). - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -/* in-line qsort implementation. Differs from traditional qsort() routine - * in that it is a macro, not a function, and instead of passing an address - * of a comparison routine to the function, it is possible to inline - * comparison routine, thus speeding up sorting a lot. - * - * Usage: - * #include "iqsort.h" - * #define islt(a,b) (strcmp((*a),(*b))<0) - * char *arr[]; - * int n; - * QSORT(char*, arr, n, islt); - * - * The "prototype" and 4 arguments are: - * QSORT(TYPE,BASE,NELT,ISLT) - * 1) type of each element, TYPE, - * 2) address of the beginning of the array, of type TYPE*, - * 3) number of elements in the array, and - * 4) comparision routine. - * Array pointer and number of elements are referenced only once. - * This is similar to a call - * qsort(BASE,NELT,sizeof(TYPE),ISLT) - * with the difference in last parameter. - * Note the islt macro/routine (it receives pointers to two elements): - * the only condition of interest is whenever one element is less than - * another, no other conditions (greather than, equal to etc) are tested. - * So, for example, to define integer sort, use: - * #define islt(a,b) ((*a)<(*b)) - * QSORT(int, arr, n, islt) - * - * The macro could be used to implement a sorting function (see examples - * below), or to implement the sorting algorithm inline. That is, either - * create a sorting function and use it whenever you want to sort something, - * or use QSORT() macro directly instead a call to such routine. Note that - * the macro expands to quite some code (compiled size of int qsort on x86 - * is about 700..800 bytes). - * - * Using this macro directly it isn't possible to implement traditional - * qsort() routine, because the macro assumes sizeof(element) == sizeof(TYPE), - * while qsort() allows element size to be different. - * - * Several ready-to-use examples: - * - * Sorting array of integers: - * void int_qsort(int *arr, unsigned n) { - * #define int_lt(a,b) ((*a)<(*b)) - * QSORT(int, arr, n, int_lt); - * } - * - * Sorting array of string pointers: - * void str_qsort(char *arr[], unsigned n) { - * #define str_lt(a,b) (strcmp((*a),(*b)) < 0) - * QSORT(char*, arr, n, str_lt); - * } - * - * Sorting array of structures: - * - * struct elt { - * int key; - * ... - * }; - * void elt_qsort(struct elt *arr, unsigned n) { - * #define elt_lt(a,b) ((a)->key < (b)->key) - * QSORT(struct elt, arr, n, elt_lt); - * } - * - * And so on. - */ - -/* Swap two items pointed to by A and B using temporary buffer t. */ -#define _QSORT_SWAP(a, b, t) ((void)((t = *a), (*a = *b), (*b = t))) - -/* Discontinue quicksort algorithm when partition gets below this size. - This particular magic number was chosen to work best on a Sun 4/260. */ -#define _QSORT_MAX_THRESH 4 - -/* Stack node declarations used to store unfulfilled partition obligations - * (inlined in QSORT). -typedef struct { - QSORT_TYPE *_lo, *_hi; -} qsort_stack_node; - */ - -/* The next 4 #defines implement a very fast in-line stack abstraction. */ -/* The stack needs log (total_elements) entries (we could even subtract - log(MAX_THRESH)). Since total_elements has type unsigned, we get as - upper bound for log (total_elements): - bits per byte (CHAR_BIT) * sizeof(unsigned). */ -#define _QSORT_STACK_SIZE (8 * sizeof(unsigned)) -#define _QSORT_PUSH(top, low, high) \ - (((top->_lo = (low)), (top->_hi = (high)), ++top)) -#define _QSORT_POP(low, high, top) \ - ((--top, (low = top->_lo), (high = top->_hi))) -#define _QSORT_STACK_NOT_EMPTY (_stack < _top) - - -/* Order size using quicksort. This implementation incorporates - four optimizations discussed in Sedgewick: - - 1. Non-recursive, using an explicit stack of pointer that store the - next array partition to sort. To save time, this maximum amount - of space required to store an array of SIZE_MAX is allocated on the - stack. Assuming a 32-bit (64 bit) integer for size_t, this needs - only 32 * sizeof(stack_node) == 256 bytes (for 64 bit: 1024 bytes). - Pretty cheap, actually. - - 2. Chose the pivot element using a median-of-three decision tree. - This reduces the probability of selecting a bad pivot value and - eliminates certain extraneous comparisons. - - 3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving - insertion sort to order the MAX_THRESH items within each partition. - This is a big win, since insertion sort is faster for small, mostly - sorted array segments. - - 4. The larger of the two sub-partitions is always pushed onto the - stack first, with the algorithm then concentrating on the - smaller partition. This *guarantees* no more than log (total_elems) - stack size is needed (actually O(1) in this case)! */ - -/* The main code starts here... */ -#define QSORT(QSORT_TYPE,QSORT_BASE,QSORT_NELT,QSORT_LT) \ -{ \ - QSORT_TYPE *const _base = (QSORT_BASE); \ - const unsigned _elems = (QSORT_NELT); \ - QSORT_TYPE _hold; \ - \ - /* Don't declare two variables of type QSORT_TYPE in a single \ - * statement: eg `TYPE a, b;', in case if TYPE is a pointer, \ - * expands to `type* a, b;' wich isn't what we want. \ - */ \ - \ - if (_elems > _QSORT_MAX_THRESH) { \ - QSORT_TYPE *_lo = _base; \ - QSORT_TYPE *_hi = _lo + _elems - 1; \ - struct { \ - QSORT_TYPE *_hi; QSORT_TYPE *_lo; \ - } _stack[_QSORT_STACK_SIZE], *_top = _stack + 1; \ - \ - while (_QSORT_STACK_NOT_EMPTY) { \ - QSORT_TYPE *_left_ptr; QSORT_TYPE *_right_ptr; \ - \ - /* Select median value from among LO, MID, and HI. Rearrange \ - LO and HI so the three values are sorted. This lowers the \ - probability of picking a pathological pivot value and \ - skips a comparison for both the LEFT_PTR and RIGHT_PTR in \ - the while loops. */ \ - \ - QSORT_TYPE *_mid = _lo + ((_hi - _lo) >> 1); \ - \ - if (QSORT_LT (_mid, _lo)) \ - _QSORT_SWAP (_mid, _lo, _hold); \ - if (QSORT_LT (_hi, _mid)) { \ - _QSORT_SWAP (_mid, _hi, _hold); \ - if (QSORT_LT (_mid, _lo)) \ - _QSORT_SWAP (_mid, _lo, _hold); \ - } \ - \ - _left_ptr = _lo + 1; \ - _right_ptr = _hi - 1; \ - \ - /* Here's the famous ``collapse the walls'' section of quicksort. \ - Gotta like those tight inner loops! They are the main reason \ - that this algorithm runs much faster than others. */ \ - do { \ - while (QSORT_LT (_left_ptr, _mid)) \ - ++_left_ptr; \ - \ - while (QSORT_LT (_mid, _right_ptr)) \ - --_right_ptr; \ - \ - if (_left_ptr < _right_ptr) { \ - _QSORT_SWAP (_left_ptr, _right_ptr, _hold); \ - if (_mid == _left_ptr) \ - _mid = _right_ptr; \ - else if (_mid == _right_ptr) \ - _mid = _left_ptr; \ - ++_left_ptr; \ - --_right_ptr; \ - } \ - else if (_left_ptr == _right_ptr) { \ - ++_left_ptr; \ - --_right_ptr; \ - break; \ - } \ - } while (_left_ptr <= _right_ptr); \ - \ - /* Set up pointers for next iteration. First determine whether \ - left and right partitions are below the threshold size. If so, \ - ignore one or both. Otherwise, push the larger partition's \ - bounds on the stack and continue sorting the smaller one. */ \ - \ - if (_right_ptr - _lo <= _QSORT_MAX_THRESH) { \ - if (_hi - _left_ptr <= _QSORT_MAX_THRESH) \ - /* Ignore both small partitions. */ \ - _QSORT_POP (_lo, _hi, _top); \ - else \ - /* Ignore small left partition. */ \ - _lo = _left_ptr; \ - } \ - else if (_hi - _left_ptr <= _QSORT_MAX_THRESH) \ - /* Ignore small right partition. */ \ - _hi = _right_ptr; \ - else if (_right_ptr - _lo > _hi - _left_ptr) { \ - /* Push larger left partition indices. */ \ - _QSORT_PUSH (_top, _lo, _right_ptr); \ - _lo = _left_ptr; \ - } \ - else { \ - /* Push larger right partition indices. */ \ - _QSORT_PUSH (_top, _left_ptr, _hi); \ - _hi = _right_ptr; \ - } \ - } \ - } \ - \ - /* Once the BASE array is partially sorted by quicksort the rest \ - is completely sorted using insertion sort, since this is efficient \ - for partitions below MAX_THRESH size. BASE points to the \ - beginning of the array to sort, and END_PTR points at the very \ - last element in the array (*not* one beyond it!). */ \ - \ - { \ - QSORT_TYPE *const _end_ptr = _base + _elems - 1; \ - QSORT_TYPE *_tmp_ptr = _base; \ - register QSORT_TYPE *_run_ptr; \ - QSORT_TYPE *_thresh; \ - \ - _thresh = _base + _QSORT_MAX_THRESH; \ - if (_thresh > _end_ptr) \ - _thresh = _end_ptr; \ - \ - /* Find smallest element in first threshold and place it at the \ - array's beginning. This is the smallest array element, \ - and the operation speeds up insertion sort's inner loop. */ \ - \ - for (_run_ptr = _tmp_ptr + 1; _run_ptr <= _thresh; ++_run_ptr) \ - if (QSORT_LT (_run_ptr, _tmp_ptr)) \ - _tmp_ptr = _run_ptr; \ - \ - if (_tmp_ptr != _base) \ - _QSORT_SWAP (_tmp_ptr, _base, _hold); \ - \ - /* Insertion sort, running from left-hand-side \ - * up to right-hand-side. */ \ - \ - _run_ptr = _base + 1; \ - while (++_run_ptr <= _end_ptr) { \ - _tmp_ptr = _run_ptr - 1; \ - while (QSORT_LT (_run_ptr, _tmp_ptr)) \ - --_tmp_ptr; \ - \ - ++_tmp_ptr; \ - if (_tmp_ptr != _run_ptr) { \ - QSORT_TYPE *_trav = _run_ptr + 1; \ - while (--_trav >= _run_ptr) { \ - QSORT_TYPE *_hi; QSORT_TYPE *_lo; \ - _hold = *_trav; \ - \ - for (_hi = _lo = _trav; --_lo >= _tmp_ptr; _hi = _lo) \ - *_hi = *_lo; \ - *_hi = _hold; \ - } \ - } \ - } \ - } \ - \ -} +#ifndef _MPLV2_LICENSE_ +#include "qsort_gnu.h" +#else +#include "qsort_bsd.h" +#endif diff --git a/utils/qsort_bsd.h b/utils/qsort_bsd.h new file mode 100644 index 0000000..da7cb57 --- /dev/null +++ b/utils/qsort_bsd.h @@ -0,0 +1,173 @@ +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)qsort.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include +/* __FBSDID("$FreeBSD: head/lib/libc/stdlib/qsort.c 175317 2008-01-14 09:21:34Z das $"); */ + +#include + +static inline char *med3(char *, char *, char *); +static inline void swapfunc(char *, char *, int, int); + +#define min(a, b) (a) < (b) ? a : b + +/* + * QSORT routine from Bentley & McIlroy's "Engineering a Sort Function". + */ +#define swapcode(TYPE, parmi, parmj, n) { \ + long i = (n) / sizeof (TYPE); \ + TYPE *pi = (TYPE *) (parmi); \ + TYPE *pj = (TYPE *) (parmj); \ + do { \ + TYPE t = *pi; \ + *pi++ = *pj; \ + *pj++ = t; \ + } while (--i > 0); \ +} + +#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \ + es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1; + +static inline void +swapfunc(a, b, n, swaptype) + char *a, *b; + int n, swaptype; +{ + if(swaptype <= 1) + swapcode(long, a, b, n) + else + swapcode(char, a, b, n) +} + +#define swap(a, b) \ + if (swaptype == 0) { \ + long t = *(long *)(a); \ + *(long *)(a) = *(long *)(b); \ + *(long *)(b) = t; \ + } else \ + swapfunc(a, b, es, swaptype) + +#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype) + +static inline char * +med3(char *a, char *b, char *c) +{ + return QSORT_LT(a, b) < 0 ? + (QSORT_LT(b, c) < 0 ? b : (QSORT_LT(a, c) < 0 ? c : a )) + :(QSORT_LT(b, c) > 0 ? b : (QSORT_LT(a, c) < 0 ? a : c )); +} + +void +QSORT(void *arr, size_t n) +{ + char *pa, *pb, *pc, *pd, *pl, *pm, *pn, *a; + size_t d, r; + int cmp_result; + int swaptype, swap_cnt; + size_t es = sizeof (QSORT_TYPE); + + a = (char *)arr; +loop: SWAPINIT(a, es); + swap_cnt = 0; + if (n < 7) { + for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es) + for (pl = pm; + pl > (char *)a && QSORT_LT(pl - es, pl) > 0; + pl -= es) + swap(pl, pl - es); + return; + } + pm = (char *)a + (n / 2) * es; + if (n > 7) { + pl = a; + pn = (char *)a + (n - 1) * es; + if (n > 40) { + d = (n / 8) * es; + pl = med3(pl, pl + d, pl + 2 * d); + pm = med3(pm - d, pm, pm + d); + pn = med3(pn - 2 * d, pn - d, pn); + } + pm = med3(pl, pm, pn); + } + swap(a, pm); + pa = pb = (char *)a + es; + + pc = pd = (char *)a + (n - 1) * es; + for (;;) { + while (pb <= pc && (cmp_result = QSORT_LT(pb, a)) <= 0) { + if (cmp_result == 0) { + swap_cnt = 1; + swap(pa, pb); + pa += es; + } + pb += es; + } + while (pb <= pc && (cmp_result = QSORT_LT(pc, a)) >= 0) { + if (cmp_result == 0) { + swap_cnt = 1; + swap(pc, pd); + pd -= es; + } + pc -= es; + } + if (pb > pc) + break; + swap(pb, pc); + swap_cnt = 1; + pb += es; + pc -= es; + } + if (swap_cnt == 0) { /* Switch to insertion sort */ + for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es) + for (pl = pm; + pl > (char *)a && QSORT_LT(pl - es, pl) > 0; + pl -= es) + swap(pl, pl - es); + return; + } + + pn = (char *)a + n * es; + r = min(pa - (char *)a, pb - pa); + vecswap(a, pb - r, r); + r = min(pd - pc, pn - pd - es); + vecswap(pb, pn - r, r); + if ((r = pb - pa) > es) + QSORT(a, r / es); + if ((r = pd - pc) > es) { + /* Iterate rather than recurse to save stack space */ + a = pn - r; + n = r / es; + goto loop; + } +/* QSORT(pn - r, r / es);*/ +} + diff --git a/utils/qsort_gnu.h b/utils/qsort_gnu.h new file mode 100644 index 0000000..b72d19f --- /dev/null +++ b/utils/qsort_gnu.h @@ -0,0 +1,314 @@ +/* + * This file is a part of Pcompress, a chunked parallel multi- + * algorithm lossless compression and decompression program. + * + * Copyright (C) 2012-2013 Moinak Ghosh. All rights reserved. + * Use is subject to license terms. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program. + * If not, see . + * + * moinakg@belenix.org, http://moinakg.wordpress.com/ + */ + +/* $Id: qsort.h,v 1.5 2008-01-28 18:16:49 mjt Exp $ + * Adopted from GNU glibc by Mjt. + * See stdlib/qsort.c in glibc */ + +/* Copyright (C) 1991, 1992, 1996, 1997, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Douglas C. Schmidt (schmidt@ics.uci.edu). + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* in-line qsort implementation. Differs from traditional qsort() routine + * in that it is a macro, not a function, and instead of passing an address + * of a comparison routine to the function, it is possible to inline + * comparison routine, thus speeding up sorting a lot. + * + * Usage: + * #include "iqsort.h" + * #define islt(a,b) (strcmp((*a),(*b))<0) + * char *arr[]; + * int n; + * QSORT(char*, arr, n, islt); + * + * The "prototype" and 4 arguments are: + * QSORT(TYPE,BASE,NELT,ISLT) + * 1) type of each element, TYPE, + * 2) address of the beginning of the array, of type TYPE*, + * 3) number of elements in the array, and + * 4) comparision routine. + * Array pointer and number of elements are referenced only once. + * This is similar to a call + * qsort(BASE,NELT,sizeof(TYPE),ISLT) + * with the difference in last parameter. + * Note the islt macro/routine (it receives pointers to two elements): + * the only condition of interest is whenever one element is less than + * another, no other conditions (greather than, equal to etc) are tested. + * So, for example, to define integer sort, use: + * #define islt(a,b) ((*a)<(*b)) + * QSORT(int, arr, n, islt) + * + * The macro could be used to implement a sorting function (see examples + * below), or to implement the sorting algorithm inline. That is, either + * create a sorting function and use it whenever you want to sort something, + * or use QSORT() macro directly instead a call to such routine. Note that + * the macro expands to quite some code (compiled size of int qsort on x86 + * is about 700..800 bytes). + * + * Using this macro directly it isn't possible to implement traditional + * qsort() routine, because the macro assumes sizeof(element) == sizeof(TYPE), + * while qsort() allows element size to be different. + * + * Several ready-to-use examples: + * + * Sorting array of integers: + * void int_qsort(int *arr, unsigned n) { + * #define int_lt(a,b) ((*a)<(*b)) + * QSORT(int, arr, n, int_lt); + * } + * + * Sorting array of string pointers: + * void str_qsort(char *arr[], unsigned n) { + * #define str_lt(a,b) (strcmp((*a),(*b)) < 0) + * QSORT(char*, arr, n, str_lt); + * } + * + * Sorting array of structures: + * + * struct elt { + * int key; + * ... + * }; + * void elt_qsort(struct elt *arr, unsigned n) { + * #define elt_lt(a,b) ((a)->key < (b)->key) + * QSORT(struct elt, arr, n, elt_lt); + * } + * + * And so on. + */ + +/* Swap two items pointed to by A and B using temporary buffer t. */ +#define _QSORT_SWAP(a, b, t) ((void)((t = *a), (*a = *b), (*b = t))) + +/* Discontinue quicksort algorithm when partition gets below this size. + This particular magic number was chosen to work best on a Sun 4/260. */ +#define _QSORT_MAX_THRESH 4 + +/* Stack node declarations used to store unfulfilled partition obligations + * (inlined in QSORT). +typedef struct { + QSORT_TYPE *_lo, *_hi; +} qsort_stack_node; + */ + +/* The next 4 #defines implement a very fast in-line stack abstraction. */ +/* The stack needs log (total_elements) entries (we could even subtract + log(MAX_THRESH)). Since total_elements has type unsigned, we get as + upper bound for log (total_elements): + bits per byte (CHAR_BIT) * sizeof(unsigned). */ +#define _QSORT_STACK_SIZE (8 * sizeof(unsigned)) +#define _QSORT_PUSH(top, low, high) \ + (((top->_lo = (low)), (top->_hi = (high)), ++top)) +#define _QSORT_POP(low, high, top) \ + ((--top, (low = top->_lo), (high = top->_hi))) +#define _QSORT_STACK_NOT_EMPTY (_stack < _top) + + +/* Order size using quicksort. This implementation incorporates + four optimizations discussed in Sedgewick: + + 1. Non-recursive, using an explicit stack of pointer that store the + next array partition to sort. To save time, this maximum amount + of space required to store an array of SIZE_MAX is allocated on the + stack. Assuming a 32-bit (64 bit) integer for size_t, this needs + only 32 * sizeof(stack_node) == 256 bytes (for 64 bit: 1024 bytes). + Pretty cheap, actually. + + 2. Chose the pivot element using a median-of-three decision tree. + This reduces the probability of selecting a bad pivot value and + eliminates certain extraneous comparisons. + + 3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving + insertion sort to order the MAX_THRESH items within each partition. + This is a big win, since insertion sort is faster for small, mostly + sorted array segments. + + 4. The larger of the two sub-partitions is always pushed onto the + stack first, with the algorithm then concentrating on the + smaller partition. This *guarantees* no more than log (total_elems) + stack size is needed (actually O(1) in this case)! */ + +/* The main code starts here... */ +#define QSORT(QSORT_BASE,QSORT_NELT) \ +{ \ + QSORT_TYPE *const _base = (QSORT_BASE); \ + const unsigned _elems = (QSORT_NELT); \ + QSORT_TYPE _hold; \ + \ + /* Don't declare two variables of type QSORT_TYPE in a single \ + * statement: eg `TYPE a, b;', in case if TYPE is a pointer, \ + * expands to `type* a, b;' wich isn't what we want. \ + */ \ + \ + if (_elems > _QSORT_MAX_THRESH) { \ + QSORT_TYPE *_lo = _base; \ + QSORT_TYPE *_hi = _lo + _elems - 1; \ + struct { \ + QSORT_TYPE *_hi; QSORT_TYPE *_lo; \ + } _stack[_QSORT_STACK_SIZE], *_top = _stack + 1; \ + \ + while (_QSORT_STACK_NOT_EMPTY) { \ + QSORT_TYPE *_left_ptr; QSORT_TYPE *_right_ptr; \ + \ + /* Select median value from among LO, MID, and HI. Rearrange \ + LO and HI so the three values are sorted. This lowers the \ + probability of picking a pathological pivot value and \ + skips a comparison for both the LEFT_PTR and RIGHT_PTR in \ + the while loops. */ \ + \ + QSORT_TYPE *_mid = _lo + ((_hi - _lo) >> 1); \ + \ + if (QSORT_LT (_mid, _lo)) \ + _QSORT_SWAP (_mid, _lo, _hold); \ + if (QSORT_LT (_hi, _mid)) { \ + _QSORT_SWAP (_mid, _hi, _hold); \ + if (QSORT_LT (_mid, _lo)) \ + _QSORT_SWAP (_mid, _lo, _hold); \ + } \ + \ + _left_ptr = _lo + 1; \ + _right_ptr = _hi - 1; \ + \ + /* Here's the famous ``collapse the walls'' section of quicksort. \ + Gotta like those tight inner loops! They are the main reason \ + that this algorithm runs much faster than others. */ \ + do { \ + while (QSORT_LT (_left_ptr, _mid)) \ + ++_left_ptr; \ + \ + while (QSORT_LT (_mid, _right_ptr)) \ + --_right_ptr; \ + \ + if (_left_ptr < _right_ptr) { \ + _QSORT_SWAP (_left_ptr, _right_ptr, _hold); \ + if (_mid == _left_ptr) \ + _mid = _right_ptr; \ + else if (_mid == _right_ptr) \ + _mid = _left_ptr; \ + ++_left_ptr; \ + --_right_ptr; \ + } \ + else if (_left_ptr == _right_ptr) { \ + ++_left_ptr; \ + --_right_ptr; \ + break; \ + } \ + } while (_left_ptr <= _right_ptr); \ + \ + /* Set up pointers for next iteration. First determine whether \ + left and right partitions are below the threshold size. If so, \ + ignore one or both. Otherwise, push the larger partition's \ + bounds on the stack and continue sorting the smaller one. */ \ + \ + if (_right_ptr - _lo <= _QSORT_MAX_THRESH) { \ + if (_hi - _left_ptr <= _QSORT_MAX_THRESH) \ + /* Ignore both small partitions. */ \ + _QSORT_POP (_lo, _hi, _top); \ + else \ + /* Ignore small left partition. */ \ + _lo = _left_ptr; \ + } \ + else if (_hi - _left_ptr <= _QSORT_MAX_THRESH) \ + /* Ignore small right partition. */ \ + _hi = _right_ptr; \ + else if (_right_ptr - _lo > _hi - _left_ptr) { \ + /* Push larger left partition indices. */ \ + _QSORT_PUSH (_top, _lo, _right_ptr); \ + _lo = _left_ptr; \ + } \ + else { \ + /* Push larger right partition indices. */ \ + _QSORT_PUSH (_top, _left_ptr, _hi); \ + _hi = _right_ptr; \ + } \ + } \ + } \ + \ + /* Once the BASE array is partially sorted by quicksort the rest \ + is completely sorted using insertion sort, since this is efficient \ + for partitions below MAX_THRESH size. BASE points to the \ + beginning of the array to sort, and END_PTR points at the very \ + last element in the array (*not* one beyond it!). */ \ + \ + { \ + QSORT_TYPE *const _end_ptr = _base + _elems - 1; \ + QSORT_TYPE *_tmp_ptr = _base; \ + register QSORT_TYPE *_run_ptr; \ + QSORT_TYPE *_thresh; \ + \ + _thresh = _base + _QSORT_MAX_THRESH; \ + if (_thresh > _end_ptr) \ + _thresh = _end_ptr; \ + \ + /* Find smallest element in first threshold and place it at the \ + array's beginning. This is the smallest array element, \ + and the operation speeds up insertion sort's inner loop. */ \ + \ + for (_run_ptr = _tmp_ptr + 1; _run_ptr <= _thresh; ++_run_ptr) \ + if (QSORT_LT (_run_ptr, _tmp_ptr)) \ + _tmp_ptr = _run_ptr; \ + \ + if (_tmp_ptr != _base) \ + _QSORT_SWAP (_tmp_ptr, _base, _hold); \ + \ + /* Insertion sort, running from left-hand-side \ + * up to right-hand-side. */ \ + \ + _run_ptr = _base + 1; \ + while (++_run_ptr <= _end_ptr) { \ + _tmp_ptr = _run_ptr - 1; \ + while (QSORT_LT (_run_ptr, _tmp_ptr)) \ + --_tmp_ptr; \ + \ + ++_tmp_ptr; \ + if (_tmp_ptr != _run_ptr) { \ + QSORT_TYPE *_trav = _run_ptr + 1; \ + while (--_trav >= _run_ptr) { \ + QSORT_TYPE *_hi; QSORT_TYPE *_lo; \ + _hold = *_trav; \ + \ + for (_hi = _lo = _trav; --_lo >= _tmp_ptr; _hi = _lo) \ + *_hi = *_lo; \ + *_hi = _hold; \ + } \ + } \ + } \ + } \ + \ +} diff --git a/utils/xxhash.h b/utils/xxhash.h index 9c45ba4..9bc1fa8 100644 --- a/utils/xxhash.h +++ b/utils/xxhash.h @@ -20,7 +20,7 @@ * If not, see . * * moinakg@belenix.org, http://moinakg.wordpress.com/ - * + * */ /*