diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-05 11:19:16 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-07-24 09:53:24 +0000 |
commit | b5f8ee61a7f7e9bd291dd26b0585d03eb686c941 (patch) | |
tree | d4d31289c39fc00da064a825df13a0b98ce95b10 /web/server/h2o/libh2o/deps/klib | |
parent | Adding upstream version 1.44.3. (diff) | |
download | netdata-upstream.tar.xz netdata-upstream.zip |
Adding upstream version 1.46.3.upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
53 files changed, 0 insertions, 10866 deletions
diff --git a/web/server/h2o/libh2o/deps/klib/.gitignore b/web/server/h2o/libh2o/deps/klib/.gitignore deleted file mode 100644 index 010a8ebe6..000000000 --- a/web/server/h2o/libh2o/deps/klib/.gitignore +++ /dev/null @@ -1,40 +0,0 @@ -# General -*.a -*.dSYM/ -*.la -*.lo -*.o -*.opensdf -*.orig -*.sdf -*.suo -*.swp -*.tests -*.vcxproj.filters -*.vcxproj.user -*~ -.git -TAGS - -# Mac/Xcode-specfic -xcuserdata -contents.xcworkspacedata -.DS_Store -._* - -# Test byproducts -test/kbtree_test -test/khash_keith -test/khash_keith2 -test/khash_test -test/klist_test -test/kmin_test -test/kseq_bench -test/kseq_bench2 -test/kseq_test -test/ksort_test -test/ksort_test-stl -test/kstring_bench -test/kstring_bench2 -test/kstring_test -test/kvec_test diff --git a/web/server/h2o/libh2o/deps/klib/README.md b/web/server/h2o/libh2o/deps/klib/README.md deleted file mode 100644 index ddd74f470..000000000 --- a/web/server/h2o/libh2o/deps/klib/README.md +++ /dev/null @@ -1,237 +0,0 @@ -#Klib: a Generic Library in C - -##<a name="overview"></a>Overview - -Klib is a standalone and lightweight C library distributed under [MIT/X11 -license][1]. Most components are independent of external libraries, except the -standard C library, and independent of each other. To use a component of this -library, you only need to copy a couple of files to your source code tree -without worrying about library dependencies. - -Klib strives for efficiency and a small memory footprint. Some components, such -as khash.h, kbtree.h, ksort.h and kvec.h, are among the most efficient -implementations of similar algorithms or data structures in all programming -languages, in terms of both speed and memory use. - -A new documentation is available [here](http://attractivechaos.github.io/klib/) -which includes most information in this README file. - -####Common components - -* [khash.h][khash]: generic hash table based on [double hashing][2]. -* [kbtree.h][kbtree]: generic search tree based on [B-tree][3]. -* [ksort.h][ksort]: generic sort, including [introsort][4], [merge sort][5], [heap sort][6], [comb sort][7], [Knuth shuffle][8] and the [k-small][9] algorithm. -* [kseq.h][kseq]: generic stream buffer and a [FASTA][10]/[FASTQ][11] format parser. -* kvec.h: generic dynamic array. -* klist.h: generic single-linked list and [memory pool][12]. -* kstring.{h,c}: basic string library. -* kmath.{h,c}: numerical routines including [MT19937-64][13] [pseudorandom generator][14], basic [nonlinear programming][15] and a few special math functions. - -####Components for more specific use cases - -* ksa.c: constructing [suffix arrays][16] for strings with multiple sentinels, based on a revised [SAIS algorithm][17]. -* knetfile.{h,c}: random access to remote files on HTTP or FTP. -* kopen.c: smart stream opening. -* khmm.{h,c}: basic [HMM][18] library. -* ksw.(h,c}: Striped [Smith-Waterman algorithm][19]. -* knhx.{h,c}: [Newick tree format][20] parser. - - -##<a name="methodology"></a>Methodology - -For the implementation of generic [containers][21], klib extensively uses C -macros. To use these data structures, we usually need to instantiate methods by -expanding a long macro. This makes the source code look unusual or even ugly -and adds difficulty to debugging. Unfortunately, for efficient generic -programming in C that lacks [template][22], using macros is the only -solution. Only with macros, we can write a generic container which, once -instantiated, compete with a type-specific container in efficiency. Some -generic libraries in C, such as [Glib][23], use the `void*` type to implement -containers. These implementations are usually slower and use more memory than -klib (see [this benchmark][31]). - -To effectively use klib, it is important to understand how it achieves generic -programming. We will use the hash table library as an example: - - #include "khash.h" - KHASH_MAP_INIT_INT(m32, char) // instantiate structs and methods - int main() { - int ret, is_missing; - khint_t k; - khash_t(m32) *h = kh_init(m32); // allocate a hash table - k = kh_put(m32, h, 5, &ret); // insert a key to the hash table - if (!ret) kh_del(m32, h, k); - kh_value(h, k) = 10; // set the value - k = kh_get(m32, h, 10); // query the hash table - is_missing = (k == kh_end(h)); // test if the key is present - k = kh_get(m32, h, 5); - kh_del(m32, h, k); // remove a key-value pair - for (k = kh_begin(h); k != kh_end(h); ++k) // traverse - if (kh_exist(h, k)) // test if a bucket contains data - kh_value(h, k) = 1; - kh_destroy(m32, h); // deallocate the hash table - return 0; - } - -In this example, the second line instantiates a hash table with `unsigned` as -the key type and `char` as the value type. `m32` names such a type of hash table. -All types and functions associated with this name are macros, which will be -explained later. Macro `kh_init()` initiates a hash table and `kh_destroy()` -frees it. `kh_put()` inserts a key and returns the iterator (or the position) -in the hash table. `kh_get()` and `kh_del()` get a key and delete an element, -respectively. Macro `kh_exist()` tests if an iterator (or a position) is filled -with data. - -An immediate question is this piece of code does not look like a valid C -program (e.g. lacking semicolon, assignment to an _apparent_ function call and -_apparent_ undefined `m32` 'variable'). To understand why the code is correct, -let's go a bit further into the source code of `khash.h`, whose skeleton looks -like: - - #define KHASH_INIT(name, SCOPE, key_t, val_t, is_map, _hashf, _hasheq) \ - typedef struct { \ - int n_buckets, size, n_occupied, upper_bound; \ - unsigned *flags; \ - key_t *keys; \ - val_t *vals; \ - } kh_##name##_t; \ - SCOPE inline kh_##name##_t *init_##name() { \ - return (kh_##name##_t*)calloc(1, sizeof(kh_##name##_t)); \ - } \ - SCOPE inline int get_##name(kh_##name##_t *h, key_t k) \ - ... \ - SCOPE inline void destroy_##name(kh_##name##_t *h) { \ - if (h) { \ - free(h->keys); free(h->flags); free(h->vals); free(h); \ - } \ - } - - #define _int_hf(key) (unsigned)(key) - #define _int_heq(a, b) (a == b) - #define khash_t(name) kh_##name##_t - #define kh_value(h, k) ((h)->vals[k]) - #define kh_begin(h, k) 0 - #define kh_end(h) ((h)->n_buckets) - #define kh_init(name) init_##name() - #define kh_get(name, h, k) get_##name(h, k) - #define kh_destroy(name, h) destroy_##name(h) - ... - #define KHASH_MAP_INIT_INT(name, val_t) \ - KHASH_INIT(name, static, unsigned, val_t, is_map, _int_hf, _int_heq) - -`KHASH_INIT()` is a huge macro defining all the structs and methods. When this -macro is called, all the code inside it will be inserted by the [C -preprocess][37] to the place where it is called. If the macro is called -multiple times, multiple copies of the code will be inserted. To avoid naming -conflict of hash tables with different key-value types, the library uses [token -concatenation][36], which is a preprocessor feature whereby we can substitute -part of a symbol based on the parameter of the macro. In the end, the C -preprocessor will generate the following code and feed it to the compiler -(macro `kh_exist(h,k)` is a little complex and not expanded for simplicity): - - typedef struct { - int n_buckets, size, n_occupied, upper_bound; - unsigned *flags; - unsigned *keys; - char *vals; - } kh_m32_t; - static inline kh_m32_t *init_m32() { - return (kh_m32_t*)calloc(1, sizeof(kh_m32_t)); - } - static inline int get_m32(kh_m32_t *h, unsigned k) - ... - static inline void destroy_m32(kh_m32_t *h) { - if (h) { - free(h->keys); free(h->flags); free(h->vals); free(h); - } - } - - int main() { - int ret, is_missing; - khint_t k; - kh_m32_t *h = init_m32(); - k = put_m32(h, 5, &ret); - if (!ret) del_m32(h, k); - h->vals[k] = 10; - k = get_m32(h, 10); - is_missing = (k == h->n_buckets); - k = get_m32(h, 5); - del_m32(h, k); - for (k = 0; k != h->n_buckets; ++k) - if (kh_exist(h, k)) h->vals[k] = 1; - destroy_m32(h); - return 0; - } - -This is the C program we know. - -From this example, we can see that macros and the C preprocessor plays a key -role in klib. Klib is fast partly because the compiler knows the key-value -type at the compile time and is able to optimize the code to the same level -as type-specific code. A generic library written with `void*` will not get such -performance boost. - -Massively inserting code upon instantiation may remind us of C++'s slow -compiling speed and huge binary size when STL/boost is in use. Klib is much -better in this respect due to its small code size and component independency. -Inserting several hundreds lines of code won't make compiling obviously slower. - -##<a name="resources"></a>Resources - -* Library documentation, if present, is available in the header files. Examples -can be found in the [test/][24] directory. -* **Obsolete** documentation of the hash table library can be found at -[SourceForge][25]. This README is partly adapted from the old documentation. -* [Blog post][26] describing the hash table library. -* [Blog post][27] on why using `void*` for generic programming may be inefficient. -* [Blog post][28] on the generic stream buffer. -* [Blog post][29] evaluating the performance of `kvec.h`. -* [Blog post][30] arguing B-tree may be a better data structure than a binary search tree. -* [Blog post][31] evaluating the performance of `khash.h` and `kbtree.h` among many other implementations. -[An older version][33] of the benchmark is also available. -* [Blog post][34] benchmarking internal sorting algorithms and implementations. -* [Blog post][32] on the k-small algorithm. -* [Blog post][35] on the Hooke-Jeeve's algorithm for nonlinear programming. - -[1]: http://en.wikipedia.org/wiki/MIT_License -[2]: http://en.wikipedia.org/wiki/Double_hashing -[3]: http://en.wikipedia.org/wiki/B-tree -[4]: http://en.wikipedia.org/wiki/Introsort -[5]: http://en.wikipedia.org/wiki/Merge_sort -[6]: http://en.wikipedia.org/wiki/Heapsort -[7]: http://en.wikipedia.org/wiki/Comb_sort -[8]: http://en.wikipedia.org/wiki/Fisher-Yates_shuffle -[9]: http://en.wikipedia.org/wiki/Selection_algorithm -[10]: http://en.wikipedia.org/wiki/FASTA_format -[11]: http://en.wikipedia.org/wiki/FASTQ_format -[12]: http://en.wikipedia.org/wiki/Memory_pool -[13]: http://en.wikipedia.org/wiki/Mersenne_twister -[14]: http://en.wikipedia.org/wiki/Pseudorandom_generator -[15]: http://en.wikipedia.org/wiki/Nonlinear_programming -[16]: http://en.wikipedia.org/wiki/Suffix_array -[17]: https://sites.google.com/site/yuta256/sais -[18]: http://en.wikipedia.org/wiki/Hidden_Markov_model -[19]: http://en.wikipedia.org/wiki/Smith-Waterman_algorithm -[20]: http://en.wikipedia.org/wiki/Newick_format -[21]: http://en.wikipedia.org/wiki/Container_(abstract_data_type) -[22]: http://en.wikipedia.org/wiki/Template_(C%2B%2B) -[23]: http://en.wikipedia.org/wiki/GLib -[24]: https://github.com/attractivechaos/klib/tree/master/test -[25]: http://klib.sourceforge.net/ -[26]: http://attractivechaos.wordpress.com/2008/09/02/implementing-generic-hash-library-in-c/ -[27]: http://attractivechaos.wordpress.com/2008/10/02/using-void-in-generic-c-programming-may-be-inefficient/ -[28]: http://attractivechaos.wordpress.com/2008/10/11/a-generic-buffered-stream-wrapper/ -[29]: http://attractivechaos.wordpress.com/2008/09/19/c-array-vs-c-vector/ -[30]: http://attractivechaos.wordpress.com/2008/09/24/b-tree-vs-binary-search-tree/ -[31]: http://attractivechaos.wordpress.com/2008/10/07/another-look-at-my-old-benchmark/ -[32]: http://attractivechaos.wordpress.com/2008/09/13/calculating-median/ -[33]: http://attractivechaos.wordpress.com/2008/08/28/comparison-of-hash-table-libraries/ -[34]: http://attractivechaos.wordpress.com/2008/08/28/comparison-of-internal-sorting-algorithms/ -[35]: http://attractivechaos.wordpress.com/2008/08/24/derivative-free-optimization-dfo/ -[36]: http://en.wikipedia.org/wiki/C_preprocessor#Token_concatenation -[37]: http://en.wikipedia.org/wiki/C_preprocessor - -[kbtree]: http://attractivechaos.github.io/klib/#KBtree%3A%20generic%20ordered%20map:%5B%5BKBtree%3A%20generic%20ordered%20map%5D%5D -[khash]: http://attractivechaos.github.io/klib/#Khash%3A%20generic%20hash%20table:%5B%5BKhash%3A%20generic%20hash%20table%5D%5D -[kseq]: http://attractivechaos.github.io/klib/#Kseq%3A%20stream%20buffer%20and%20FASTA%2FQ%20parser:%5B%5BKseq%3A%20stream%20buffer%20and%20FASTA%2FQ%20parser%5D%5D -[ksort]: http://attractivechaos.github.io/klib/#Ksort%3A%20sorting%2C%20shuffling%2C%20heap%20and%20k-small:%5B%5BKsort%3A%20sorting%2C%20shuffling%2C%20heap%20and%20k-small%5D%5D diff --git a/web/server/h2o/libh2o/deps/klib/bgzf.c b/web/server/h2o/libh2o/deps/klib/bgzf.c deleted file mode 100644 index 9833414f9..000000000 --- a/web/server/h2o/libh2o/deps/klib/bgzf.c +++ /dev/null @@ -1,555 +0,0 @@ -/* The MIT License - - Copyright (c) 2008 Broad Institute / Massachusetts Institute of Technology - 2011 Attractive Chaos <attractor@live.co.uk> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <assert.h> -#include <sys/types.h> -#include "bgzf.h" - -#ifdef _USE_KNETFILE -#include "knetfile.h" -typedef knetFile *_bgzf_file_t; -#define _bgzf_open(fn, mode) knet_open(fn, mode) -#define _bgzf_dopen(fp, mode) knet_dopen(fp, mode) -#define _bgzf_close(fp) knet_close(fp) -#define _bgzf_fileno(fp) ((fp)->fd) -#define _bgzf_tell(fp) knet_tell(fp) -#define _bgzf_seek(fp, offset, whence) knet_seek(fp, offset, whence) -#define _bgzf_read(fp, buf, len) knet_read(fp, buf, len) -#define _bgzf_write(fp, buf, len) knet_write(fp, buf, len) -#else // ~defined(_USE_KNETFILE) -#if defined(_WIN32) || defined(_MSC_VER) -#define ftello(fp) ftell(fp) -#define fseeko(fp, offset, whence) fseek(fp, offset, whence) -#else // ~defined(_WIN32) -extern off_t ftello(FILE *stream); -extern int fseeko(FILE *stream, off_t offset, int whence); -#endif // ~defined(_WIN32) -typedef FILE *_bgzf_file_t; -#define _bgzf_open(fn, mode) fopen(fn, mode) -#define _bgzf_dopen(fp, mode) fdopen(fp, mode) -#define _bgzf_close(fp) fclose(fp) -#define _bgzf_fileno(fp) fileno(fp) -#define _bgzf_tell(fp) ftello(fp) -#define _bgzf_seek(fp, offset, whence) fseeko(fp, offset, whence) -#define _bgzf_read(fp, buf, len) fread(buf, 1, len, fp) -#define _bgzf_write(fp, buf, len) fwrite(buf, 1, len, fp) -#endif // ~define(_USE_KNETFILE) - -#define BLOCK_HEADER_LENGTH 18 -#define BLOCK_FOOTER_LENGTH 8 - -/* BGZF/GZIP header (speciallized from RFC 1952; little endian): - +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ - | 31|139| 8| 4| 0| 0|255| 6| 66| 67| 2|BLK_LEN| - +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ -*/ -static const uint8_t g_magic[19] = "\037\213\010\4\0\0\0\0\0\377\6\0\102\103\2\0\0\0"; - -#ifdef BGZF_CACHE -typedef struct { - int size; - uint8_t *block; - int64_t end_offset; -} cache_t; -#include "khash.h" -KHASH_MAP_INIT_INT64(cache, cache_t) -#endif - -static inline void packInt16(uint8_t *buffer, uint16_t value) -{ - buffer[0] = value; - buffer[1] = value >> 8; -} - -static inline int unpackInt16(const uint8_t *buffer) -{ - return buffer[0] | buffer[1] << 8; -} - -static inline void packInt32(uint8_t *buffer, uint32_t value) -{ - buffer[0] = value; - buffer[1] = value >> 8; - buffer[2] = value >> 16; - buffer[3] = value >> 24; -} - -static BGZF *bgzf_read_init() -{ - BGZF *fp; - fp = calloc(1, sizeof(BGZF)); - fp->open_mode = 'r'; - fp->uncompressed_block = malloc(BGZF_MAX_BLOCK_SIZE); - fp->compressed_block = malloc(BGZF_MAX_BLOCK_SIZE); -#ifdef BGZF_CACHE - fp->cache = kh_init(cache); -#endif - return fp; -} - -static BGZF *bgzf_write_init(int compress_level) // compress_level==-1 for the default level -{ - BGZF *fp; - fp = calloc(1, sizeof(BGZF)); - fp->open_mode = 'w'; - fp->uncompressed_block = malloc(BGZF_MAX_BLOCK_SIZE); - fp->compressed_block = malloc(BGZF_MAX_BLOCK_SIZE); - fp->compress_level = compress_level < 0? Z_DEFAULT_COMPRESSION : compress_level; // Z_DEFAULT_COMPRESSION==-1 - if (fp->compress_level > 9) fp->compress_level = Z_DEFAULT_COMPRESSION; - return fp; -} -// get the compress level from the mode string -static int mode2level(const char *__restrict mode) -{ - int i, compress_level = -1; - for (i = 0; mode[i]; ++i) - if (mode[i] >= '0' && mode[i] <= '9') break; - if (mode[i]) compress_level = (int)mode[i] - '0'; - if (strchr(mode, 'u')) compress_level = 0; - return compress_level; -} - -BGZF *bgzf_open(const char *path, const char *mode) -{ - BGZF *fp = 0; - if (strchr(mode, 'r') || strchr(mode, 'R')) { - _bgzf_file_t fpr; - if ((fpr = _bgzf_open(path, "r")) == 0) return 0; - fp = bgzf_read_init(); - fp->fp = fpr; - } else if (strchr(mode, 'w') || strchr(mode, 'W')) { - FILE *fpw; - if ((fpw = fopen(path, "w")) == 0) return 0; - fp = bgzf_write_init(mode2level(mode)); - fp->fp = fpw; - } - return fp; -} - -BGZF *bgzf_dopen(int fd, const char *mode) -{ - BGZF *fp = 0; - if (strchr(mode, 'r') || strchr(mode, 'R')) { - _bgzf_file_t fpr; - if ((fpr = _bgzf_dopen(fd, "r")) == 0) return 0; - fp = bgzf_read_init(); - fp->fp = fpr; - } else if (strchr(mode, 'w') || strchr(mode, 'W')) { - FILE *fpw; - if ((fpw = fdopen(fd, "w")) == 0) return 0; - fp = bgzf_write_init(mode2level(mode)); - fp->fp = fpw; - } - return fp; -} - -// Deflate the block in fp->uncompressed_block into fp->compressed_block. Also adds an extra field that stores the compressed block length. -static int deflate_block(BGZF *fp, int block_length) -{ - uint8_t *buffer = fp->compressed_block; - int buffer_size = BGZF_BLOCK_SIZE; - int input_length = block_length; - int compressed_length = 0; - int remaining; - uint32_t crc; - - assert(block_length <= BGZF_BLOCK_SIZE); // guaranteed by the caller - memcpy(buffer, g_magic, BLOCK_HEADER_LENGTH); // the last two bytes are a place holder for the length of the block - while (1) { // loop to retry for blocks that do not compress enough - int status; - z_stream zs; - zs.zalloc = NULL; - zs.zfree = NULL; - zs.next_in = fp->uncompressed_block; - zs.avail_in = input_length; - zs.next_out = (void*)&buffer[BLOCK_HEADER_LENGTH]; - zs.avail_out = buffer_size - BLOCK_HEADER_LENGTH - BLOCK_FOOTER_LENGTH; - status = deflateInit2(&zs, fp->compress_level, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY); // -15 to disable zlib header/footer - if (status != Z_OK) { - fp->errcode |= BGZF_ERR_ZLIB; - return -1; - } - status = deflate(&zs, Z_FINISH); - if (status != Z_STREAM_END) { // not compressed enough - deflateEnd(&zs); // reset the stream - if (status == Z_OK) { // reduce the size and recompress - input_length -= 1024; - assert(input_length > 0); // logically, this should not happen - continue; - } - fp->errcode |= BGZF_ERR_ZLIB; - return -1; - } - if (deflateEnd(&zs) != Z_OK) { - fp->errcode |= BGZF_ERR_ZLIB; - return -1; - } - compressed_length = zs.total_out; - compressed_length += BLOCK_HEADER_LENGTH + BLOCK_FOOTER_LENGTH; - assert(compressed_length <= BGZF_BLOCK_SIZE); - break; - } - - assert(compressed_length > 0); - packInt16((uint8_t*)&buffer[16], compressed_length - 1); // write the compressed_length; -1 to fit 2 bytes - crc = crc32(0L, NULL, 0L); - crc = crc32(crc, fp->uncompressed_block, input_length); - packInt32((uint8_t*)&buffer[compressed_length-8], crc); - packInt32((uint8_t*)&buffer[compressed_length-4], input_length); - - remaining = block_length - input_length; - if (remaining > 0) { - assert(remaining <= input_length); - memcpy(fp->uncompressed_block, fp->uncompressed_block + input_length, remaining); - } - fp->block_offset = remaining; - return compressed_length; -} - -// Inflate the block in fp->compressed_block into fp->uncompressed_block -static int inflate_block(BGZF* fp, int block_length) -{ - z_stream zs; - zs.zalloc = NULL; - zs.zfree = NULL; - zs.next_in = fp->compressed_block + 18; - zs.avail_in = block_length - 16; - zs.next_out = fp->uncompressed_block; - zs.avail_out = BGZF_BLOCK_SIZE; - - if (inflateInit2(&zs, -15) != Z_OK) { - fp->errcode |= BGZF_ERR_ZLIB; - return -1; - } - if (inflate(&zs, Z_FINISH) != Z_STREAM_END) { - inflateEnd(&zs); - fp->errcode |= BGZF_ERR_ZLIB; - return -1; - } - if (inflateEnd(&zs) != Z_OK) { - fp->errcode |= BGZF_ERR_ZLIB; - return -1; - } - return zs.total_out; -} - -static int check_header(const uint8_t *header) -{ - return (header[0] == 31 && header[1] == 139 && header[2] == 8 && (header[3] & 4) != 0 - && unpackInt16((uint8_t*)&header[10]) == 6 - && header[12] == 'B' && header[13] == 'C' - && unpackInt16((uint8_t*)&header[14]) == 2); -} - -#ifdef BGZF_CACHE -static void free_cache(BGZF *fp) -{ - khint_t k; - khash_t(cache) *h = (khash_t(cache)*)fp->cache; - if (fp->open_mode != 'r') return; - for (k = kh_begin(h); k < kh_end(h); ++k) - if (kh_exist(h, k)) free(kh_val(h, k).block); - kh_destroy(cache, h); -} - -static int load_block_from_cache(BGZF *fp, int64_t block_address) -{ - khint_t k; - cache_t *p; - khash_t(cache) *h = (khash_t(cache)*)fp->cache; - k = kh_get(cache, h, block_address); - if (k == kh_end(h)) return 0; - p = &kh_val(h, k); - if (fp->block_length != 0) fp->block_offset = 0; - fp->block_address = block_address; - fp->block_length = p->size; - memcpy(fp->uncompressed_block, p->block, BGZF_BLOCK_SIZE); - _bgzf_seek((_bgzf_file_t)fp->fp, p->end_offset, SEEK_SET); - return p->size; -} - -static void cache_block(BGZF *fp, int size) -{ - int ret; - khint_t k; - cache_t *p; - khash_t(cache) *h = (khash_t(cache)*)fp->cache; - if (BGZF_BLOCK_SIZE >= fp->cache_size) return; - if ((kh_size(h) + 1) * BGZF_BLOCK_SIZE > fp->cache_size) { - /* A better way would be to remove the oldest block in the - * cache, but here we remove a random one for simplicity. This - * should not have a big impact on performance. */ - for (k = kh_begin(h); k < kh_end(h); ++k) - if (kh_exist(h, k)) break; - if (k < kh_end(h)) { - free(kh_val(h, k).block); - kh_del(cache, h, k); - } - } - k = kh_put(cache, h, fp->block_address, &ret); - if (ret == 0) return; // if this happens, a bug! - p = &kh_val(h, k); - p->size = fp->block_length; - p->end_offset = fp->block_address + size; - p->block = malloc(BGZF_BLOCK_SIZE); - memcpy(kh_val(h, k).block, fp->uncompressed_block, BGZF_BLOCK_SIZE); -} -#else -static void free_cache(BGZF *fp) {} -static int load_block_from_cache(BGZF *fp, int64_t block_address) {return 0;} -static void cache_block(BGZF *fp, int size) {} -#endif - -int bgzf_read_block(BGZF *fp) -{ - uint8_t header[BLOCK_HEADER_LENGTH], *compressed_block; - int count, size = 0, block_length, remaining; - int64_t block_address; - block_address = _bgzf_tell((_bgzf_file_t)fp->fp); - if (load_block_from_cache(fp, block_address)) return 0; - count = _bgzf_read(fp->fp, header, sizeof(header)); - if (count == 0) { // no data read - fp->block_length = 0; - return 0; - } - if (count != sizeof(header) || !check_header(header)) { - fp->errcode |= BGZF_ERR_HEADER; - return -1; - } - size = count; - block_length = unpackInt16((uint8_t*)&header[16]) + 1; // +1 because when writing this number, we used "-1" - compressed_block = (uint8_t*)fp->compressed_block; - memcpy(compressed_block, header, BLOCK_HEADER_LENGTH); - remaining = block_length - BLOCK_HEADER_LENGTH; - count = _bgzf_read(fp->fp, &compressed_block[BLOCK_HEADER_LENGTH], remaining); - if (count != remaining) { - fp->errcode |= BGZF_ERR_IO; - return -1; - } - size += count; - if ((count = inflate_block(fp, block_length)) < 0) return -1; - if (fp->block_length != 0) fp->block_offset = 0; // Do not reset offset if this read follows a seek. - fp->block_address = block_address; - fp->block_length = count; - cache_block(fp, size); - return 0; -} - -ssize_t bgzf_read(BGZF *fp, void *data, ssize_t length) -{ - ssize_t bytes_read = 0; - uint8_t *output = data; - if (length <= 0) return 0; - assert(fp->open_mode == 'r'); - while (bytes_read < length) { - int copy_length, available = fp->block_length - fp->block_offset; - uint8_t *buffer; - if (available <= 0) { - if (bgzf_read_block(fp) != 0) return -1; - available = fp->block_length - fp->block_offset; - if (available <= 0) break; - } - copy_length = length - bytes_read < available? length - bytes_read : available; - buffer = fp->uncompressed_block; - memcpy(output, buffer + fp->block_offset, copy_length); - fp->block_offset += copy_length; - output += copy_length; - bytes_read += copy_length; - } - if (fp->block_offset == fp->block_length) { - fp->block_address = _bgzf_tell((_bgzf_file_t)fp->fp); - fp->block_offset = fp->block_length = 0; - } - return bytes_read; -} - -int bgzf_flush(BGZF *fp) -{ - assert(fp->open_mode == 'w'); - while (fp->block_offset > 0) { - int block_length; - block_length = deflate_block(fp, fp->block_offset); - if (block_length < 0) return -1; - if (fwrite(fp->compressed_block, 1, block_length, fp->fp) != block_length) { - fp->errcode |= BGZF_ERR_IO; // possibly truncated file - return -1; - } - fp->block_address += block_length; - } - return 0; -} - -int bgzf_flush_try(BGZF *fp, ssize_t size) -{ - if (fp->block_offset + size > BGZF_BLOCK_SIZE) - return bgzf_flush(fp); - return -1; -} - -ssize_t bgzf_write(BGZF *fp, const void *data, ssize_t length) -{ - const uint8_t *input = data; - int block_length = BGZF_BLOCK_SIZE, bytes_written; - assert(fp->open_mode == 'w'); - input = data; - bytes_written = 0; - while (bytes_written < length) { - uint8_t* buffer = fp->uncompressed_block; - int copy_length = block_length - fp->block_offset < length - bytes_written? block_length - fp->block_offset : length - bytes_written; - memcpy(buffer + fp->block_offset, input, copy_length); - fp->block_offset += copy_length; - input += copy_length; - bytes_written += copy_length; - if (fp->block_offset == block_length && bgzf_flush(fp)) break; - } - return bytes_written; -} - -int bgzf_close(BGZF* fp) -{ - int ret, count, block_length; - if (fp == 0) return -1; - if (fp->open_mode == 'w') { - if (bgzf_flush(fp) != 0) return -1; - block_length = deflate_block(fp, 0); // write an empty block - count = fwrite(fp->compressed_block, 1, block_length, fp->fp); - if (fflush(fp->fp) != 0) { - fp->errcode |= BGZF_ERR_IO; - return -1; - } - } - ret = fp->open_mode == 'w'? fclose(fp->fp) : _bgzf_close(fp->fp); - if (ret != 0) return -1; - free(fp->uncompressed_block); - free(fp->compressed_block); - free_cache(fp); - free(fp); - return 0; -} - -void bgzf_set_cache_size(BGZF *fp, int cache_size) -{ - if (fp) fp->cache_size = cache_size; -} - -int bgzf_check_EOF(BGZF *fp) -{ - static uint8_t magic[28] = "\037\213\010\4\0\0\0\0\0\377\6\0\102\103\2\0\033\0\3\0\0\0\0\0\0\0\0\0"; - uint8_t buf[28]; - off_t offset; - offset = _bgzf_tell((_bgzf_file_t)fp->fp); - if (_bgzf_seek(fp->fp, -28, SEEK_END) < 0) return 0; - _bgzf_read(fp->fp, buf, 28); - _bgzf_seek(fp->fp, offset, SEEK_SET); - return (memcmp(magic, buf, 28) == 0)? 1 : 0; -} - -int64_t bgzf_seek(BGZF* fp, int64_t pos, int where) -{ - int block_offset; - int64_t block_address; - - if (fp->open_mode != 'r' || where != SEEK_SET) { - fp->errcode |= BGZF_ERR_MISUSE; - return -1; - } - block_offset = pos & 0xFFFF; - block_address = pos >> 16; - if (_bgzf_seek(fp->fp, block_address, SEEK_SET) < 0) { - fp->errcode |= BGZF_ERR_IO; - return -1; - } - fp->block_length = 0; // indicates current block has not been loaded - fp->block_address = block_address; - fp->block_offset = block_offset; - return 0; -} - -int bgzf_is_bgzf(const char *fn) -{ - uint8_t buf[16]; - int n; - _bgzf_file_t fp; - if ((fp = _bgzf_open(fn, "r")) == 0) return 0; - n = _bgzf_read(fp, buf, 16); - _bgzf_close(fp); - if (n != 16) return 0; - return memcmp(g_magic, buf, 16) == 0? 1 : 0; -} - -int bgzf_getc(BGZF *fp) -{ - int c; - if (fp->block_offset >= fp->block_length) { - if (bgzf_read_block(fp) != 0) return -2; /* error */ - if (fp->block_length == 0) return -1; /* end-of-file */ - } - c = ((unsigned char*)fp->uncompressed_block)[fp->block_offset++]; - if (fp->block_offset == fp->block_length) { - fp->block_address = _bgzf_tell((_bgzf_file_t)fp->fp); - fp->block_offset = 0; - fp->block_length = 0; - } - return c; -} - -#ifndef kroundup32 -#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) -#endif - -int bgzf_getline(BGZF *fp, int delim, kstring_t *str) -{ - int l, state = 0; - unsigned char *buf = (unsigned char*)fp->uncompressed_block; - str->l = 0; - do { - if (fp->block_offset >= fp->block_length) { - if (bgzf_read_block(fp) != 0) { state = -2; break; } - if (fp->block_length == 0) { state = -1; break; } - } - for (l = fp->block_offset; l < fp->block_length && buf[l] != delim; ++l); - if (l < fp->block_length) state = 1; - l -= fp->block_offset; - if (str->l + l + 1 >= str->m) { - str->m = str->l + l + 2; - kroundup32(str->m); - str->s = (char*)realloc(str->s, str->m); - } - memcpy(str->s + str->l, buf + fp->block_offset, l); - str->l += l; - fp->block_offset += l + 1; - if (fp->block_offset >= fp->block_length) { - fp->block_address = _bgzf_tell((_bgzf_file_t)fp->fp); - fp->block_offset = 0; - fp->block_length = 0; - } - } while (state == 0); - if (str->l == 0 && state < 0) return state; - str->s[str->l] = 0; - return str->l; -} diff --git a/web/server/h2o/libh2o/deps/klib/bgzf.h b/web/server/h2o/libh2o/deps/klib/bgzf.h deleted file mode 100644 index 29fe0e5da..000000000 --- a/web/server/h2o/libh2o/deps/klib/bgzf.h +++ /dev/null @@ -1,196 +0,0 @@ -/* The MIT License - - Copyright (c) 2008 Broad Institute / Massachusetts Institute of Technology - 2011 Attractive Chaos <attractor@live.co.uk> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - -/* The BGZF library was originally written by Bob Handsaker from the Broad - * Institute. It was later improved by the SAMtools developers. */ - -#ifndef __BGZF_H -#define __BGZF_H - -#include <stdint.h> -#include <stdio.h> -#include <zlib.h> - -#define BGZF_BLOCK_SIZE 0x10000 -#define BGZF_MAX_BLOCK_SIZE 0x10000 - -#define BGZF_ERR_ZLIB 1 -#define BGZF_ERR_HEADER 2 -#define BGZF_ERR_IO 4 -#define BGZF_ERR_MISUSE 8 - -typedef struct { - int open_mode:8, compress_level:8, errcode:16; - int cache_size; - int block_length, block_offset; - int64_t block_address; - void *uncompressed_block, *compressed_block; - void *cache; // a pointer to a hash table - void *fp; // actual file handler; FILE* on writing; FILE* or knetFile* on reading -} BGZF; - -#ifndef KSTRING_T -#define KSTRING_T kstring_t -typedef struct __kstring_t { - size_t l, m; - char *s; -} kstring_t; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - - /****************** - * Basic routines * - ******************/ - - /** - * Open an existing file descriptor for reading or writing. - * - * @param fd file descriptor - * @param mode mode matching /[rwu0-9]+/: 'r' for reading, 'w' for writing and a digit specifies - * the zlib compression level; if both 'r' and 'w' are present, 'w' is ignored. - * @return BGZF file handler; 0 on error - */ - BGZF* bgzf_dopen(int fd, const char *mode); - - #define bgzf_fdopen(fd, mode) bgzf_dopen((fd), (mode)) // for backward compatibility - - /** - * Open the specified file for reading or writing. - */ - BGZF* bgzf_open(const char* path, const char *mode); - - /** - * Close the BGZF and free all associated resources. - * - * @param fp BGZF file handler - * @return 0 on success and -1 on error - */ - int bgzf_close(BGZF *fp); - - /** - * Read up to _length_ bytes from the file storing into _data_. - * - * @param fp BGZF file handler - * @param data data array to read into - * @param length size of data to read - * @return number of bytes actually read; 0 on end-of-file and -1 on error - */ - ssize_t bgzf_read(BGZF *fp, void *data, ssize_t length); - - /** - * Write _length_ bytes from _data_ to the file. - * - * @param fp BGZF file handler - * @param data data array to write - * @param length size of data to write - * @return number of bytes actually written; -1 on error - */ - ssize_t bgzf_write(BGZF *fp, const void *data, ssize_t length); - - /** - * Write the data in the buffer to the file. - */ - int bgzf_flush(BGZF *fp); - - /** - * Return a virtual file pointer to the current location in the file. - * No interpetation of the value should be made, other than a subsequent - * call to bgzf_seek can be used to position the file at the same point. - * Return value is non-negative on success. - */ - #define bgzf_tell(fp) ((fp->block_address << 16) | (fp->block_offset & 0xFFFF)) - - /** - * Set the file to read from the location specified by _pos_. - * - * @param fp BGZF file handler - * @param pos virtual file offset returned by bgzf_tell() - * @param whence must be SEEK_SET - * @return 0 on success and -1 on error - */ - int64_t bgzf_seek(BGZF *fp, int64_t pos, int whence); - - /** - * Check if the BGZF end-of-file (EOF) marker is present - * - * @param fp BGZF file handler opened for reading - * @return 1 if EOF is present; 0 if not or on I/O error - */ - int bgzf_check_EOF(BGZF *fp); - - /** - * Check if a file is in the BGZF format - * - * @param fn file name - * @return 1 if _fn_ is BGZF; 0 if not or on I/O error - */ - int bgzf_is_bgzf(const char *fn); - - /********************* - * Advanced routines * - *********************/ - - /** - * Set the cache size. Only effective when compiled with -DBGZF_CACHE. - * - * @param fp BGZF file handler - * @param size size of cache in bytes; 0 to disable caching (default) - */ - void bgzf_set_cache_size(BGZF *fp, int size); - - /** - * Flush the file if the remaining buffer size is smaller than _size_ - */ - int bgzf_flush_try(BGZF *fp, ssize_t size); - - /** - * Read one byte from a BGZF file. It is faster than bgzf_read() - * @param fp BGZF file handler - * @return byte read; -1 on end-of-file or error - */ - int bgzf_getc(BGZF *fp); - - /** - * Read one line from a BGZF file. It is faster than bgzf_getc() - * - * @param fp BGZF file handler - * @param delim delimitor - * @param str string to write to; must be initialized - * @return length of the string; 0 on end-of-file; negative on error - */ - int bgzf_getline(BGZF *fp, int delim, kstring_t *str); - - /** - * Read the next BGZF block. - */ - int bgzf_read_block(BGZF *fp); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/web/server/h2o/libh2o/deps/klib/kbit.h b/web/server/h2o/libh2o/deps/klib/kbit.h deleted file mode 100644 index 3793cf837..000000000 --- a/web/server/h2o/libh2o/deps/klib/kbit.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef KBIT_H -#define KBIT_H - -#include <stdint.h> - -static inline uint64_t kbi_popcount64(uint64_t y) // standard popcount; from wikipedia -{ - y -= ((y >> 1) & 0x5555555555555555ull); - y = (y & 0x3333333333333333ull) + (y >> 2 & 0x3333333333333333ull); - return ((y + (y >> 4)) & 0xf0f0f0f0f0f0f0full) * 0x101010101010101ull >> 56; -} - -static inline uint64_t kbi_DNAcount64(uint64_t y, int c) // count #A/C/G/T from a 2-bit encoded integer; from BWA -{ - // reduce nucleotide counting to bits counting - y = ((c&2)? y : ~y) >> 1 & ((c&1)? y : ~y) & 0x5555555555555555ull; - // count the number of 1s in y - y = (y & 0x3333333333333333ull) + (y >> 2 & 0x3333333333333333ull); - return ((y + (y >> 4)) & 0xf0f0f0f0f0f0f0full) * 0x101010101010101ull >> 56; -} - -#ifndef kroundup32 // round a 32-bit integer to the next closet integer; from "bit twiddling hacks" -#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) -#endif - -#ifndef kbi_swap -#define kbi_swap(a, b) (((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b))) // from "bit twiddling hacks" -#endif - -#endif diff --git a/web/server/h2o/libh2o/deps/klib/kbtree.h b/web/server/h2o/libh2o/deps/klib/kbtree.h deleted file mode 100644 index 5ed5330b9..000000000 --- a/web/server/h2o/libh2o/deps/klib/kbtree.h +++ /dev/null @@ -1,384 +0,0 @@ -/*- - * Copyright 1997-1999, 2001, John-Mark Gurney. - * 2008-2009, Attractive Chaos <attractor@live.co.uk> - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. - */ - -#ifndef __AC_KBTREE_H -#define __AC_KBTREE_H - -#include <stdlib.h> -#include <string.h> -#include <stdint.h> - -typedef struct { - int32_t is_internal:1, n:31; -} kbnode_t; - -#define __KB_KEY(type, x) ((type*)((char*)x + 4)) -#define __KB_PTR(btr, x) ((kbnode_t**)((char*)x + btr->off_ptr)) - -#define __KB_TREE_T(name) \ - typedef struct { \ - kbnode_t *root; \ - int off_key, off_ptr, ilen, elen; \ - int n, t; \ - int n_keys, n_nodes; \ - } kbtree_##name##_t; - -#define __KB_INIT(name, key_t) \ - kbtree_##name##_t *kb_init_##name(int size) \ - { \ - kbtree_##name##_t *b; \ - b = (kbtree_##name##_t*)calloc(1, sizeof(kbtree_##name##_t)); \ - b->t = ((size - 4 - sizeof(void*)) / (sizeof(void*) + sizeof(key_t)) + 1) >> 1; \ - if (b->t < 2) { \ - free(b); return 0; \ - } \ - b->n = 2 * b->t - 1; \ - b->off_ptr = 4 + b->n * sizeof(key_t); \ - b->ilen = (4 + sizeof(void*) + b->n * (sizeof(void*) + sizeof(key_t)) + 3) >> 2 << 2; \ - b->elen = (b->off_ptr + 3) >> 2 << 2; \ - b->root = (kbnode_t*)calloc(1, b->ilen); \ - ++b->n_nodes; \ - return b; \ - } - -#define __kb_destroy(b) do { \ - int i, max = 8; \ - kbnode_t *x, **top, **stack = 0; \ - if (b) { \ - top = stack = (kbnode_t**)calloc(max, sizeof(kbnode_t*)); \ - *top++ = (b)->root; \ - while (top != stack) { \ - x = *--top; \ - if (x->is_internal == 0) { free(x); continue; } \ - for (i = 0; i <= x->n; ++i) \ - if (__KB_PTR(b, x)[i]) { \ - if (top - stack == max) { \ - max <<= 1; \ - stack = (kbnode_t**)realloc(stack, max * sizeof(kbnode_t*)); \ - top = stack + (max>>1); \ - } \ - *top++ = __KB_PTR(b, x)[i]; \ - } \ - free(x); \ - } \ - } \ - free(b); free(stack); \ - } while (0) - -#define __kb_get_first(key_t, b, ret) do { \ - kbnode_t *__x = (b)->root; \ - while (__KB_PTR(b, __x)[0] != 0) \ - __x = __KB_PTR(b, __x)[0]; \ - (ret) = __KB_KEY(key_t, __x)[0]; \ - } while (0) - -#define __KB_GET_AUX0(name, key_t, __cmp) \ - static inline int __kb_get_aux_##name(const kbnode_t * __restrict x, const key_t * __restrict k, int *r) \ - { \ - int tr, *rr, begin, end, n = x->n >> 1; \ - if (x->n == 0) return -1; \ - if (__cmp(*k, __KB_KEY(key_t, x)[n]) < 0) { \ - begin = 0; end = n; \ - } else { begin = n; end = x->n - 1; } \ - rr = r? r : &tr; \ - n = end; \ - while (n >= begin && (*rr = __cmp(*k, __KB_KEY(key_t, x)[n])) < 0) --n; \ - return n; \ - } - -#define __KB_GET_AUX1(name, key_t, __cmp) \ - static inline int __kb_getp_aux_##name(const kbnode_t * __restrict x, const key_t * __restrict k, int *r) \ - { \ - int tr, *rr, begin = 0, end = x->n; \ - if (x->n == 0) return -1; \ - rr = r? r : &tr; \ - while (begin < end) { \ - int mid = (begin + end) >> 1; \ - if (__cmp(__KB_KEY(key_t, x)[mid], *k) < 0) begin = mid + 1; \ - else end = mid; \ - } \ - if (begin == x->n) { *rr = 1; return x->n - 1; } \ - if ((*rr = __cmp(*k, __KB_KEY(key_t, x)[begin])) < 0) --begin; \ - return begin; \ - } - -#define __KB_GET(name, key_t) \ - static key_t *kb_getp_##name(kbtree_##name##_t *b, const key_t * __restrict k) \ - { \ - int i, r = 0; \ - kbnode_t *x = b->root; \ - while (x) { \ - i = __kb_getp_aux_##name(x, k, &r); \ - if (i >= 0 && r == 0) return &__KB_KEY(key_t, x)[i]; \ - if (x->is_internal == 0) return 0; \ - x = __KB_PTR(b, x)[i + 1]; \ - } \ - return 0; \ - } \ - static inline key_t *kb_get_##name(kbtree_##name##_t *b, const key_t k) \ - { \ - return kb_getp_##name(b, &k); \ - } - -#define __KB_INTERVAL(name, key_t) \ - static void kb_intervalp_##name(kbtree_##name##_t *b, const key_t * __restrict k, key_t **lower, key_t **upper) \ - { \ - int i, r = 0; \ - kbnode_t *x = b->root; \ - *lower = *upper = 0; \ - while (x) { \ - i = __kb_getp_aux_##name(x, k, &r); \ - if (i >= 0 && r == 0) { \ - *lower = *upper = &__KB_KEY(key_t, x)[i]; \ - return; \ - } \ - if (i >= 0) *lower = &__KB_KEY(key_t, x)[i]; \ - if (i < x->n - 1) *upper = &__KB_KEY(key_t, x)[i + 1]; \ - if (x->is_internal == 0) return; \ - x = __KB_PTR(b, x)[i + 1]; \ - } \ - } \ - static inline void kb_interval_##name(kbtree_##name##_t *b, const key_t k, key_t **lower, key_t **upper) \ - { \ - kb_intervalp_##name(b, &k, lower, upper); \ - } - -#define __KB_PUT(name, key_t, __cmp) \ - /* x must be an internal node */ \ - static void __kb_split_##name(kbtree_##name##_t *b, kbnode_t *x, int i, kbnode_t *y) \ - { \ - kbnode_t *z; \ - z = (kbnode_t*)calloc(1, y->is_internal? b->ilen : b->elen); \ - ++b->n_nodes; \ - z->is_internal = y->is_internal; \ - z->n = b->t - 1; \ - memcpy(__KB_KEY(key_t, z), __KB_KEY(key_t, y) + b->t, sizeof(key_t) * (b->t - 1)); \ - if (y->is_internal) memcpy(__KB_PTR(b, z), __KB_PTR(b, y) + b->t, sizeof(void*) * b->t); \ - y->n = b->t - 1; \ - memmove(__KB_PTR(b, x) + i + 2, __KB_PTR(b, x) + i + 1, sizeof(void*) * (x->n - i)); \ - __KB_PTR(b, x)[i + 1] = z; \ - memmove(__KB_KEY(key_t, x) + i + 1, __KB_KEY(key_t, x) + i, sizeof(key_t) * (x->n - i)); \ - __KB_KEY(key_t, x)[i] = __KB_KEY(key_t, y)[b->t - 1]; \ - ++x->n; \ - } \ - static void __kb_putp_aux_##name(kbtree_##name##_t *b, kbnode_t *x, const key_t * __restrict k) \ - { \ - int i = x->n - 1; \ - if (x->is_internal == 0) { \ - i = __kb_getp_aux_##name(x, k, 0); \ - if (i != x->n - 1) \ - memmove(__KB_KEY(key_t, x) + i + 2, __KB_KEY(key_t, x) + i + 1, (x->n - i - 1) * sizeof(key_t)); \ - __KB_KEY(key_t, x)[i + 1] = *k; \ - ++x->n; \ - } else { \ - i = __kb_getp_aux_##name(x, k, 0) + 1; \ - if (__KB_PTR(b, x)[i]->n == 2 * b->t - 1) { \ - __kb_split_##name(b, x, i, __KB_PTR(b, x)[i]); \ - if (__cmp(*k, __KB_KEY(key_t, x)[i]) > 0) ++i; \ - } \ - __kb_putp_aux_##name(b, __KB_PTR(b, x)[i], k); \ - } \ - } \ - static void kb_putp_##name(kbtree_##name##_t *b, const key_t * __restrict k) \ - { \ - kbnode_t *r, *s; \ - ++b->n_keys; \ - r = b->root; \ - if (r->n == 2 * b->t - 1) { \ - ++b->n_nodes; \ - s = (kbnode_t*)calloc(1, b->ilen); \ - b->root = s; s->is_internal = 1; s->n = 0; \ - __KB_PTR(b, s)[0] = r; \ - __kb_split_##name(b, s, 0, r); \ - r = s; \ - } \ - __kb_putp_aux_##name(b, r, k); \ - } \ - static inline void kb_put_##name(kbtree_##name##_t *b, const key_t k) \ - { \ - kb_putp_##name(b, &k); \ - } - - -#define __KB_DEL(name, key_t) \ - static key_t __kb_delp_aux_##name(kbtree_##name##_t *b, kbnode_t *x, const key_t * __restrict k, int s) \ - { \ - int yn, zn, i, r = 0; \ - kbnode_t *xp, *y, *z; \ - key_t kp; \ - if (x == 0) return *k; \ - if (s) { /* s can only be 0, 1 or 2 */ \ - r = x->is_internal == 0? 0 : s == 1? 1 : -1; \ - i = s == 1? x->n - 1 : -1; \ - } else i = __kb_getp_aux_##name(x, k, &r); \ - if (x->is_internal == 0) { \ - if (s == 2) ++i; \ - kp = __KB_KEY(key_t, x)[i]; \ - memmove(__KB_KEY(key_t, x) + i, __KB_KEY(key_t, x) + i + 1, (x->n - i - 1) * sizeof(key_t)); \ - --x->n; \ - return kp; \ - } \ - if (r == 0) { \ - if ((yn = __KB_PTR(b, x)[i]->n) >= b->t) { \ - xp = __KB_PTR(b, x)[i]; \ - kp = __KB_KEY(key_t, x)[i]; \ - __KB_KEY(key_t, x)[i] = __kb_delp_aux_##name(b, xp, 0, 1); \ - return kp; \ - } else if ((zn = __KB_PTR(b, x)[i + 1]->n) >= b->t) { \ - xp = __KB_PTR(b, x)[i + 1]; \ - kp = __KB_KEY(key_t, x)[i]; \ - __KB_KEY(key_t, x)[i] = __kb_delp_aux_##name(b, xp, 0, 2); \ - return kp; \ - } else if (yn == b->t - 1 && zn == b->t - 1) { \ - y = __KB_PTR(b, x)[i]; z = __KB_PTR(b, x)[i + 1]; \ - __KB_KEY(key_t, y)[y->n++] = *k; \ - memmove(__KB_KEY(key_t, y) + y->n, __KB_KEY(key_t, z), z->n * sizeof(key_t)); \ - if (y->is_internal) memmove(__KB_PTR(b, y) + y->n, __KB_PTR(b, z), (z->n + 1) * sizeof(void*)); \ - y->n += z->n; \ - memmove(__KB_KEY(key_t, x) + i, __KB_KEY(key_t, x) + i + 1, (x->n - i - 1) * sizeof(key_t)); \ - memmove(__KB_PTR(b, x) + i + 1, __KB_PTR(b, x) + i + 2, (x->n - i - 1) * sizeof(void*)); \ - --x->n; \ - free(z); \ - return __kb_delp_aux_##name(b, y, k, s); \ - } \ - } \ - ++i; \ - if ((xp = __KB_PTR(b, x)[i])->n == b->t - 1) { \ - if (i > 0 && (y = __KB_PTR(b, x)[i - 1])->n >= b->t) { \ - memmove(__KB_KEY(key_t, xp) + 1, __KB_KEY(key_t, xp), xp->n * sizeof(key_t)); \ - if (xp->is_internal) memmove(__KB_PTR(b, xp) + 1, __KB_PTR(b, xp), (xp->n + 1) * sizeof(void*)); \ - __KB_KEY(key_t, xp)[0] = __KB_KEY(key_t, x)[i - 1]; \ - __KB_KEY(key_t, x)[i - 1] = __KB_KEY(key_t, y)[y->n - 1]; \ - if (xp->is_internal) __KB_PTR(b, xp)[0] = __KB_PTR(b, y)[y->n]; \ - --y->n; ++xp->n; \ - } else if (i < x->n && (y = __KB_PTR(b, x)[i + 1])->n >= b->t) { \ - __KB_KEY(key_t, xp)[xp->n++] = __KB_KEY(key_t, x)[i]; \ - __KB_KEY(key_t, x)[i] = __KB_KEY(key_t, y)[0]; \ - if (xp->is_internal) __KB_PTR(b, xp)[xp->n] = __KB_PTR(b, y)[0]; \ - --y->n; \ - memmove(__KB_KEY(key_t, y), __KB_KEY(key_t, y) + 1, y->n * sizeof(key_t)); \ - if (y->is_internal) memmove(__KB_PTR(b, y), __KB_PTR(b, y) + 1, (y->n + 1) * sizeof(void*)); \ - } else if (i > 0 && (y = __KB_PTR(b, x)[i - 1])->n == b->t - 1) { \ - __KB_KEY(key_t, y)[y->n++] = __KB_KEY(key_t, x)[i - 1]; \ - memmove(__KB_KEY(key_t, y) + y->n, __KB_KEY(key_t, xp), xp->n * sizeof(key_t)); \ - if (y->is_internal) memmove(__KB_PTR(b, y) + y->n, __KB_PTR(b, xp), (xp->n + 1) * sizeof(void*)); \ - y->n += xp->n; \ - memmove(__KB_KEY(key_t, x) + i - 1, __KB_KEY(key_t, x) + i, (x->n - i) * sizeof(key_t)); \ - memmove(__KB_PTR(b, x) + i, __KB_PTR(b, x) + i + 1, (x->n - i) * sizeof(void*)); \ - --x->n; \ - free(xp); \ - xp = y; \ - } else if (i < x->n && (y = __KB_PTR(b, x)[i + 1])->n == b->t - 1) { \ - __KB_KEY(key_t, xp)[xp->n++] = __KB_KEY(key_t, x)[i]; \ - memmove(__KB_KEY(key_t, xp) + xp->n, __KB_KEY(key_t, y), y->n * sizeof(key_t)); \ - if (xp->is_internal) memmove(__KB_PTR(b, xp) + xp->n, __KB_PTR(b, y), (y->n + 1) * sizeof(void*)); \ - xp->n += y->n; \ - memmove(__KB_KEY(key_t, x) + i, __KB_KEY(key_t, x) + i + 1, (x->n - i - 1) * sizeof(key_t)); \ - memmove(__KB_PTR(b, x) + i + 1, __KB_PTR(b, x) + i + 2, (x->n - i - 1) * sizeof(void*)); \ - --x->n; \ - free(y); \ - } \ - } \ - return __kb_delp_aux_##name(b, xp, k, s); \ - } \ - static key_t kb_delp_##name(kbtree_##name##_t *b, const key_t * __restrict k) \ - { \ - kbnode_t *x; \ - key_t ret; \ - ret = __kb_delp_aux_##name(b, b->root, k, 0); \ - --b->n_keys; \ - if (b->root->n == 0 && b->root->is_internal) { \ - --b->n_nodes; \ - x = b->root; \ - b->root = __KB_PTR(b, x)[0]; \ - free(x); \ - } \ - return ret; \ - } \ - static inline key_t kb_del_##name(kbtree_##name##_t *b, const key_t k) \ - { \ - return kb_delp_##name(b, &k); \ - } - -typedef struct { - kbnode_t *x; - int i; -} __kbstack_t; - -#define __kb_traverse(key_t, b, __func) do { \ - int __kmax = 8; \ - __kbstack_t *__kstack, *__kp; \ - __kp = __kstack = (__kbstack_t*)calloc(__kmax, sizeof(__kbstack_t)); \ - __kp->x = (b)->root; __kp->i = 0; \ - for (;;) { \ - while (__kp->x && __kp->i <= __kp->x->n) { \ - if (__kp - __kstack == __kmax - 1) { \ - __kmax <<= 1; \ - __kstack = (__kbstack_t*)realloc(__kstack, __kmax * sizeof(__kbstack_t)); \ - __kp = __kstack + (__kmax>>1) - 1; \ - } \ - (__kp+1)->i = 0; (__kp+1)->x = __kp->x->is_internal? __KB_PTR(b, __kp->x)[__kp->i] : 0; \ - ++__kp; \ - } \ - --__kp; \ - if (__kp >= __kstack) { \ - if (__kp->x && __kp->i < __kp->x->n) __func(&__KB_KEY(key_t, __kp->x)[__kp->i]); \ - ++__kp->i; \ - } else break; \ - } \ - free(__kstack); \ - } while (0) - -#define KBTREE_INIT(name, key_t, __cmp) \ - __KB_TREE_T(name) \ - __KB_INIT(name, key_t) \ - __KB_GET_AUX1(name, key_t, __cmp) \ - __KB_GET(name, key_t) \ - __KB_INTERVAL(name, key_t) \ - __KB_PUT(name, key_t, __cmp) \ - __KB_DEL(name, key_t) - -#define KB_DEFAULT_SIZE 512 - -#define kbtree_t(name) kbtree_##name##_t -#define kb_init(name, s) kb_init_##name(s) -#define kb_destroy(name, b) __kb_destroy(b) -#define kb_get(name, b, k) kb_get_##name(b, k) -#define kb_put(name, b, k) kb_put_##name(b, k) -#define kb_del(name, b, k) kb_del_##name(b, k) -#define kb_interval(name, b, k, l, u) kb_interval_##name(b, k, l, u) -#define kb_getp(name, b, k) kb_getp_##name(b, k) -#define kb_putp(name, b, k) kb_putp_##name(b, k) -#define kb_delp(name, b, k) kb_delp_##name(b, k) -#define kb_intervalp(name, b, k, l, u) kb_intervalp_##name(b, k, l, u) - -#define kb_size(b) ((b)->n_keys) - -#define kb_generic_cmp(a, b) (((b) < (a)) - ((a) < (b))) -#define kb_str_cmp(a, b) strcmp(a, b) - -#endif diff --git a/web/server/h2o/libh2o/deps/klib/kgraph.h b/web/server/h2o/libh2o/deps/klib/kgraph.h deleted file mode 100644 index af008ef7e..000000000 --- a/web/server/h2o/libh2o/deps/klib/kgraph.h +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef AC_KGRAPH_H -#define AC_KGRAPH_H - -#include <stdint.h> -#include <stdlib.h> -#include "khash.h" -#include "kbtree.h" - -typedef unsigned kgint_t; - -#define kgraph_t(name) kh_##name##_t - -#define __KG_BASIC(name, SCOPE, vertex_t, arc_t, ehn) \ - SCOPE kgraph_t(name) *kg_init_##name(void) { return kh_init(name); } \ - SCOPE void kg_destroy_##name(kgraph_t(name) *g) { \ - khint_t k; \ - if (g == 0) return; \ - for (k = kh_begin(g); k != kh_end(g); ++k) \ - if (kh_exist(g, k)) kh_destroy(ehn, kh_val(g, k)._arc); \ - kh_destroy(name, g); \ - } \ - SCOPE vertex_t *kg_get_v_##name(kgraph_t(name) *g, kgint_t v) { \ - khint_t k = kh_get(name, g, v); \ - return k == kh_end(g)? 0 : &kh_val(g, k); \ - } \ - SCOPE vertex_t *kg_put_v_##name(kgraph_t(name) *g, kgint_t v, int *absent) { \ - khint_t k; \ - k = kh_put(name, g, v, absent); \ - if (*absent) kh_val(g, k)._arc = kh_init(ehn); \ - return &kh_val(g, k); \ - } \ - SCOPE void kg_put_a_##name(kgraph_t(name) *g, kgint_t vbeg, kgint_t vend, int dir, arc_t **pb, arc_t **pe) { \ - vertex_t *p; \ - khint_t k; \ - int absent; \ - p = kg_put_v_##name(g, vbeg, &absent); \ - k = kh_put(ehn, p->_arc, vend<<2|dir, &absent); \ - *pb = &kh_val(p->_arc, k); \ - p = kg_put_v_##name(g, vend, &absent); \ - k = kh_put(ehn, p->_arc, vbeg<<2|(~dir&3), &absent); \ - *pe = &kh_val(p->_arc, k); \ - } \ - SCOPE vertex_t *kg_del_v_##name(kgraph_t(name) *g, kgint_t v) { \ - khint_t k, k0, k2, k3; \ - khash_t(ehn) *h; \ - k0 = k = kh_get(name, g, v); \ - if (k == kh_end(g)) return 0; /* not present in the graph */ \ - h = kh_val(g, k)._arc; \ - for (k = kh_begin(h); k != kh_end(h); ++k) /* remove v from its neighbors */ \ - if (kh_exist(h, k)) { \ - k2 = kh_get(name, g, kh_key(h, k)>>2); \ - /* assert(k2 != kh_end(g)); */ \ - k3 = kh_get(ehn, kh_val(g, k2)._arc, v<<2|(~kh_key(h, k)&3)); \ - /* assert(k3 != kh_end(kh_val(g, k2)._arc)); */ \ - kh_del(ehn, kh_val(g, k2)._arc, k3); \ - } \ - kh_destroy(ehn, h); \ - kh_del(name, g, k0); \ - return &kh_val(g, k0); \ - } - -#define KGRAPH_PRINT(name, SCOPE) \ - SCOPE void kg_print_##name(kgraph_t(name) *g) { \ - khint_t k, k2; \ - for (k = kh_begin(g); k != kh_end(g); ++k) \ - if (kh_exist(g, k)) { \ - printf("v %u\n", kh_key(g, k)); \ - for (k2 = kh_begin(kh_val(g, k)._arc); k2 != kh_end(kh_val(g, k)._arc); ++k2) \ - if (kh_exist(kh_val(g, k)._arc, k2) && kh_key(g, k) < kh_key(kh_val(g, k)._arc, k2)>>2) \ - printf("a %u%c%c%u\n", kh_key(g, k), "><"[kh_key(kh_val(g, k)._arc, k2)>>1&1], \ - "><"[kh_key(kh_val(g, k)._arc, k2)&1], kh_key(kh_val(g, k)._arc, k2)>>2); \ - } \ - } - -#define KGRAPH_INIT(name, SCOPE, vertex_t, arc_t, ehn) \ - KHASH_INIT2(name, SCOPE, kgint_t, vertex_t, 1, kh_int_hash_func, kh_int_hash_equal) \ - __KG_BASIC(name, SCOPE, vertex_t, arc_t, ehn) - -#endif diff --git a/web/server/h2o/libh2o/deps/klib/khash.h b/web/server/h2o/libh2o/deps/klib/khash.h deleted file mode 100644 index 5e55088b2..000000000 --- a/web/server/h2o/libh2o/deps/klib/khash.h +++ /dev/null @@ -1,619 +0,0 @@ -/* The MIT License - - Copyright (c) 2008, 2009, 2011 by Attractive Chaos <attractor@live.co.uk> - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. -*/ - -/* - An example: - -#include "khash.h" -KHASH_MAP_INIT_INT(32, char) -int main() { - int ret, is_missing; - khiter_t k; - khash_t(32) *h = kh_init(32); - k = kh_put(32, h, 5, &ret); - kh_value(h, k) = 10; - k = kh_get(32, h, 10); - is_missing = (k == kh_end(h)); - k = kh_get(32, h, 5); - kh_del(32, h, k); - for (k = kh_begin(h); k != kh_end(h); ++k) - if (kh_exist(h, k)) kh_value(h, k) = 1; - kh_destroy(32, h); - return 0; -} -*/ - -/* - 2013-05-02 (0.2.8): - - * Use quadratic probing. When the capacity is power of 2, stepping function - i*(i+1)/2 guarantees to traverse each bucket. It is better than double - hashing on cache performance and is more robust than linear probing. - - In theory, double hashing should be more robust than quadratic probing. - However, my implementation is probably not for large hash tables, because - the second hash function is closely tied to the first hash function, - which reduce the effectiveness of double hashing. - - Reference: http://research.cs.vt.edu/AVresearch/hashing/quadratic.php - - 2011-12-29 (0.2.7): - - * Minor code clean up; no actual effect. - - 2011-09-16 (0.2.6): - - * The capacity is a power of 2. This seems to dramatically improve the - speed for simple keys. Thank Zilong Tan for the suggestion. Reference: - - - http://code.google.com/p/ulib/ - - http://nothings.org/computer/judy/ - - * Allow to optionally use linear probing which usually has better - performance for random input. Double hashing is still the default as it - is more robust to certain non-random input. - - * Added Wang's integer hash function (not used by default). This hash - function is more robust to certain non-random input. - - 2011-02-14 (0.2.5): - - * Allow to declare global functions. - - 2009-09-26 (0.2.4): - - * Improve portability - - 2008-09-19 (0.2.3): - - * Corrected the example - * Improved interfaces - - 2008-09-11 (0.2.2): - - * Improved speed a little in kh_put() - - 2008-09-10 (0.2.1): - - * Added kh_clear() - * Fixed a compiling error - - 2008-09-02 (0.2.0): - - * Changed to token concatenation which increases flexibility. - - 2008-08-31 (0.1.2): - - * Fixed a bug in kh_get(), which has not been tested previously. - - 2008-08-31 (0.1.1): - - * Added destructor -*/ - - -#ifndef __AC_KHASH_H -#define __AC_KHASH_H - -/*! - @header - - Generic hash table library. - */ - -#define AC_VERSION_KHASH_H "0.2.8" - -#include <stdlib.h> -#include <string.h> -#include <limits.h> - -/* compiler specific configuration */ - -#if UINT_MAX == 0xffffffffu -typedef unsigned int khint32_t; -#elif ULONG_MAX == 0xffffffffu -typedef unsigned long khint32_t; -#endif - -#if ULONG_MAX == ULLONG_MAX -typedef unsigned long khint64_t; -#else -typedef unsigned long long khint64_t; -#endif - -#ifndef kh_inline -#ifdef _MSC_VER -#define kh_inline __inline -#else -#define kh_inline inline -#endif -#endif /* kh_inline */ - -typedef khint32_t khint_t; -typedef khint_t khiter_t; - -#define __ac_isempty(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&2) -#define __ac_isdel(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&1) -#define __ac_iseither(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&3) -#define __ac_set_isdel_false(flag, i) (flag[i>>4]&=~(1ul<<((i&0xfU)<<1))) -#define __ac_set_isempty_false(flag, i) (flag[i>>4]&=~(2ul<<((i&0xfU)<<1))) -#define __ac_set_isboth_false(flag, i) (flag[i>>4]&=~(3ul<<((i&0xfU)<<1))) -#define __ac_set_isdel_true(flag, i) (flag[i>>4]|=1ul<<((i&0xfU)<<1)) - -#define __ac_fsize(m) ((m) < 16? 1 : (m)>>4) - -#ifndef kroundup32 -#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) -#endif - -#ifndef kcalloc -#define kcalloc(N,Z) calloc(N,Z) -#endif -#ifndef kmalloc -#define kmalloc(Z) malloc(Z) -#endif -#ifndef krealloc -#define krealloc(P,Z) realloc(P,Z) -#endif -#ifndef kfree -#define kfree(P) free(P) -#endif - -static const double __ac_HASH_UPPER = 0.77; - -#define __KHASH_TYPE(name, khkey_t, khval_t) \ - typedef struct kh_##name##_s { \ - khint_t n_buckets, size, n_occupied, upper_bound; \ - khint32_t *flags; \ - khkey_t *keys; \ - khval_t *vals; \ - } kh_##name##_t; - -#define __KHASH_PROTOTYPES(name, khkey_t, khval_t) \ - extern kh_##name##_t *kh_init_##name(void); \ - extern void kh_destroy_##name(kh_##name##_t *h); \ - extern void kh_clear_##name(kh_##name##_t *h); \ - extern khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key); \ - extern int kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets); \ - extern khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret); \ - extern void kh_del_##name(kh_##name##_t *h, khint_t x); - -#define __KHASH_IMPL(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \ - SCOPE kh_##name##_t *kh_init_##name(void) { \ - return (kh_##name##_t*)kcalloc(1, sizeof(kh_##name##_t)); \ - } \ - SCOPE void kh_destroy_##name(kh_##name##_t *h) \ - { \ - if (h) { \ - kfree((void *)h->keys); kfree(h->flags); \ - kfree((void *)h->vals); \ - kfree(h); \ - } \ - } \ - SCOPE void kh_clear_##name(kh_##name##_t *h) \ - { \ - if (h && h->flags) { \ - memset(h->flags, 0xaa, __ac_fsize(h->n_buckets) * sizeof(khint32_t)); \ - h->size = h->n_occupied = 0; \ - } \ - } \ - SCOPE khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key) \ - { \ - if (h->n_buckets) { \ - khint_t k, i, last, mask, step = 0; \ - mask = h->n_buckets - 1; \ - k = __hash_func(key); i = k & mask; \ - last = i; \ - while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \ - i = (i + (++step)) & mask; \ - if (i == last) return h->n_buckets; \ - } \ - return __ac_iseither(h->flags, i)? h->n_buckets : i; \ - } else return 0; \ - } \ - SCOPE int kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets) \ - { /* This function uses 0.25*n_buckets bytes of working space instead of [sizeof(key_t+val_t)+.25]*n_buckets. */ \ - khint32_t *new_flags = 0; \ - khint_t j = 1; \ - { \ - kroundup32(new_n_buckets); \ - if (new_n_buckets < 4) new_n_buckets = 4; \ - if (h->size >= (khint_t)(new_n_buckets * __ac_HASH_UPPER + 0.5)) j = 0; /* requested size is too small */ \ - else { /* hash table size to be changed (shrink or expand); rehash */ \ - new_flags = (khint32_t*)kmalloc(__ac_fsize(new_n_buckets) * sizeof(khint32_t)); \ - if (!new_flags) return -1; \ - memset(new_flags, 0xaa, __ac_fsize(new_n_buckets) * sizeof(khint32_t)); \ - if (h->n_buckets < new_n_buckets) { /* expand */ \ - khkey_t *new_keys = (khkey_t*)krealloc((void *)h->keys, new_n_buckets * sizeof(khkey_t)); \ - if (!new_keys) { kfree(new_flags); return -1; } \ - h->keys = new_keys; \ - if (kh_is_map) { \ - khval_t *new_vals = (khval_t*)krealloc((void *)h->vals, new_n_buckets * sizeof(khval_t)); \ - if (!new_vals) { kfree(new_flags); return -1; } \ - h->vals = new_vals; \ - } \ - } /* otherwise shrink */ \ - } \ - } \ - if (j) { /* rehashing is needed */ \ - for (j = 0; j != h->n_buckets; ++j) { \ - if (__ac_iseither(h->flags, j) == 0) { \ - khkey_t key = h->keys[j]; \ - khval_t val; \ - khint_t new_mask; \ - new_mask = new_n_buckets - 1; \ - if (kh_is_map) val = h->vals[j]; \ - __ac_set_isdel_true(h->flags, j); \ - while (1) { /* kick-out process; sort of like in Cuckoo hashing */ \ - khint_t k, i, step = 0; \ - k = __hash_func(key); \ - i = k & new_mask; \ - while (!__ac_isempty(new_flags, i)) i = (i + (++step)) & new_mask; \ - __ac_set_isempty_false(new_flags, i); \ - if (i < h->n_buckets && __ac_iseither(h->flags, i) == 0) { /* kick out the existing element */ \ - { khkey_t tmp = h->keys[i]; h->keys[i] = key; key = tmp; } \ - if (kh_is_map) { khval_t tmp = h->vals[i]; h->vals[i] = val; val = tmp; } \ - __ac_set_isdel_true(h->flags, i); /* mark it as deleted in the old hash table */ \ - } else { /* write the element and jump out of the loop */ \ - h->keys[i] = key; \ - if (kh_is_map) h->vals[i] = val; \ - break; \ - } \ - } \ - } \ - } \ - if (h->n_buckets > new_n_buckets) { /* shrink the hash table */ \ - h->keys = (khkey_t*)krealloc((void *)h->keys, new_n_buckets * sizeof(khkey_t)); \ - if (kh_is_map) h->vals = (khval_t*)krealloc((void *)h->vals, new_n_buckets * sizeof(khval_t)); \ - } \ - kfree(h->flags); /* free the working space */ \ - h->flags = new_flags; \ - h->n_buckets = new_n_buckets; \ - h->n_occupied = h->size; \ - h->upper_bound = (khint_t)(h->n_buckets * __ac_HASH_UPPER + 0.5); \ - } \ - return 0; \ - } \ - SCOPE khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret) \ - { \ - khint_t x; \ - if (h->n_occupied >= h->upper_bound) { /* update the hash table */ \ - if (h->n_buckets > (h->size<<1)) { \ - if (kh_resize_##name(h, h->n_buckets - 1) < 0) { /* clear "deleted" elements */ \ - *ret = -1; return h->n_buckets; \ - } \ - } else if (kh_resize_##name(h, h->n_buckets + 1) < 0) { /* expand the hash table */ \ - *ret = -1; return h->n_buckets; \ - } \ - } /* TODO: to implement automatically shrinking; resize() already support shrinking */ \ - { \ - khint_t k, i, site, last, mask = h->n_buckets - 1, step = 0; \ - x = site = h->n_buckets; k = __hash_func(key); i = k & mask; \ - if (__ac_isempty(h->flags, i)) x = i; /* for speed up */ \ - else { \ - last = i; \ - while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \ - if (__ac_isdel(h->flags, i)) site = i; \ - i = (i + (++step)) & mask; \ - if (i == last) { x = site; break; } \ - } \ - if (x == h->n_buckets) { \ - if (__ac_isempty(h->flags, i) && site != h->n_buckets) x = site; \ - else x = i; \ - } \ - } \ - } \ - if (__ac_isempty(h->flags, x)) { /* not present at all */ \ - h->keys[x] = key; \ - __ac_set_isboth_false(h->flags, x); \ - ++h->size; ++h->n_occupied; \ - *ret = 1; \ - } else if (__ac_isdel(h->flags, x)) { /* deleted */ \ - h->keys[x] = key; \ - __ac_set_isboth_false(h->flags, x); \ - ++h->size; \ - *ret = 2; \ - } else *ret = 0; /* Don't touch h->keys[x] if present and not deleted */ \ - return x; \ - } \ - SCOPE void kh_del_##name(kh_##name##_t *h, khint_t x) \ - { \ - if (x != h->n_buckets && !__ac_iseither(h->flags, x)) { \ - __ac_set_isdel_true(h->flags, x); \ - --h->size; \ - } \ - } - -#define KHASH_DECLARE(name, khkey_t, khval_t) \ - __KHASH_TYPE(name, khkey_t, khval_t) \ - __KHASH_PROTOTYPES(name, khkey_t, khval_t) - -#define KHASH_INIT2(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \ - __KHASH_TYPE(name, khkey_t, khval_t) \ - __KHASH_IMPL(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) - -#define KHASH_INIT(name, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \ - KHASH_INIT2(name, static kh_inline, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) - -/* --- BEGIN OF HASH FUNCTIONS --- */ - -/*! @function - @abstract Integer hash function - @param key The integer [khint32_t] - @return The hash value [khint_t] - */ -#define kh_int_hash_func(key) (khint32_t)(key) -/*! @function - @abstract Integer comparison function - */ -#define kh_int_hash_equal(a, b) ((a) == (b)) -/*! @function - @abstract 64-bit integer hash function - @param key The integer [khint64_t] - @return The hash value [khint_t] - */ -#define kh_int64_hash_func(key) (khint32_t)((key)>>33^(key)^(key)<<11) -/*! @function - @abstract 64-bit integer comparison function - */ -#define kh_int64_hash_equal(a, b) ((a) == (b)) -/*! @function - @abstract const char* hash function - @param s Pointer to a null terminated string - @return The hash value - */ -static kh_inline khint_t __ac_X31_hash_string(const char *s) -{ - khint_t h = (khint_t)*s; - if (h) for (++s ; *s; ++s) h = (h << 5) - h + (khint_t)*s; - return h; -} -/*! @function - @abstract Another interface to const char* hash function - @param key Pointer to a null terminated string [const char*] - @return The hash value [khint_t] - */ -#define kh_str_hash_func(key) __ac_X31_hash_string(key) -/*! @function - @abstract Const char* comparison function - */ -#define kh_str_hash_equal(a, b) (strcmp(a, b) == 0) - -static kh_inline khint_t __ac_Wang_hash(khint_t key) -{ - key += ~(key << 15); - key ^= (key >> 10); - key += (key << 3); - key ^= (key >> 6); - key += ~(key << 11); - key ^= (key >> 16); - return key; -} -#define kh_int_hash_func2(k) __ac_Wang_hash((khint_t)key) - -/* --- END OF HASH FUNCTIONS --- */ - -/* Other convenient macros... */ - -/*! - @abstract Type of the hash table. - @param name Name of the hash table [symbol] - */ -#define khash_t(name) kh_##name##_t - -/*! @function - @abstract Initiate a hash table. - @param name Name of the hash table [symbol] - @return Pointer to the hash table [khash_t(name)*] - */ -#define kh_init(name) kh_init_##name() - -/*! @function - @abstract Destroy a hash table. - @param name Name of the hash table [symbol] - @param h Pointer to the hash table [khash_t(name)*] - */ -#define kh_destroy(name, h) kh_destroy_##name(h) - -/*! @function - @abstract Reset a hash table without deallocating memory. - @param name Name of the hash table [symbol] - @param h Pointer to the hash table [khash_t(name)*] - */ -#define kh_clear(name, h) kh_clear_##name(h) - -/*! @function - @abstract Resize a hash table. - @param name Name of the hash table [symbol] - @param h Pointer to the hash table [khash_t(name)*] - @param s New size [khint_t] - */ -#define kh_resize(name, h, s) kh_resize_##name(h, s) - -/*! @function - @abstract Insert a key to the hash table. - @param name Name of the hash table [symbol] - @param h Pointer to the hash table [khash_t(name)*] - @param k Key [type of keys] - @param r Extra return code: -1 if the operation failed; - 0 if the key is present in the hash table; - 1 if the bucket is empty (never used); 2 if the element in - the bucket has been deleted [int*] - @return Iterator to the inserted element [khint_t] - */ -#define kh_put(name, h, k, r) kh_put_##name(h, k, r) - -/*! @function - @abstract Retrieve a key from the hash table. - @param name Name of the hash table [symbol] - @param h Pointer to the hash table [khash_t(name)*] - @param k Key [type of keys] - @return Iterator to the found element, or kh_end(h) if the element is absent [khint_t] - */ -#define kh_get(name, h, k) kh_get_##name(h, k) - -/*! @function - @abstract Remove a key from the hash table. - @param name Name of the hash table [symbol] - @param h Pointer to the hash table [khash_t(name)*] - @param k Iterator to the element to be deleted [khint_t] - */ -#define kh_del(name, h, k) kh_del_##name(h, k) - -/*! @function - @abstract Test whether a bucket contains data. - @param h Pointer to the hash table [khash_t(name)*] - @param x Iterator to the bucket [khint_t] - @return 1 if containing data; 0 otherwise [int] - */ -#define kh_exist(h, x) (!__ac_iseither((h)->flags, (x))) - -/*! @function - @abstract Get key given an iterator - @param h Pointer to the hash table [khash_t(name)*] - @param x Iterator to the bucket [khint_t] - @return Key [type of keys] - */ -#define kh_key(h, x) ((h)->keys[x]) - -/*! @function - @abstract Get value given an iterator - @param h Pointer to the hash table [khash_t(name)*] - @param x Iterator to the bucket [khint_t] - @return Value [type of values] - @discussion For hash sets, calling this results in segfault. - */ -#define kh_val(h, x) ((h)->vals[x]) - -/*! @function - @abstract Alias of kh_val() - */ -#define kh_value(h, x) ((h)->vals[x]) - -/*! @function - @abstract Get the start iterator - @param h Pointer to the hash table [khash_t(name)*] - @return The start iterator [khint_t] - */ -#define kh_begin(h) (khint_t)(0) - -/*! @function - @abstract Get the end iterator - @param h Pointer to the hash table [khash_t(name)*] - @return The end iterator [khint_t] - */ -#define kh_end(h) ((h)->n_buckets) - -/*! @function - @abstract Get the number of elements in the hash table - @param h Pointer to the hash table [khash_t(name)*] - @return Number of elements in the hash table [khint_t] - */ -#define kh_size(h) ((h)->size) - -/*! @function - @abstract Get the number of buckets in the hash table - @param h Pointer to the hash table [khash_t(name)*] - @return Number of buckets in the hash table [khint_t] - */ -#define kh_n_buckets(h) ((h)->n_buckets) - -/*! @function - @abstract Iterate over the entries in the hash table - @param h Pointer to the hash table [khash_t(name)*] - @param kvar Variable to which key will be assigned - @param vvar Variable to which value will be assigned - @param code Block of code to execute - */ -#define kh_foreach(h, kvar, vvar, code) { khint_t __i; \ - for (__i = kh_begin(h); __i != kh_end(h); ++__i) { \ - if (!kh_exist(h,__i)) continue; \ - (kvar) = kh_key(h,__i); \ - (vvar) = kh_val(h,__i); \ - code; \ - } } - -/*! @function - @abstract Iterate over the values in the hash table - @param h Pointer to the hash table [khash_t(name)*] - @param vvar Variable to which value will be assigned - @param code Block of code to execute - */ -#define kh_foreach_value(h, vvar, code) { khint_t __i; \ - for (__i = kh_begin(h); __i != kh_end(h); ++__i) { \ - if (!kh_exist(h,__i)) continue; \ - (vvar) = kh_val(h,__i); \ - code; \ - } } - -/* More conenient interfaces */ - -/*! @function - @abstract Instantiate a hash set containing integer keys - @param name Name of the hash table [symbol] - */ -#define KHASH_SET_INIT_INT(name) \ - KHASH_INIT(name, khint32_t, char, 0, kh_int_hash_func, kh_int_hash_equal) - -/*! @function - @abstract Instantiate a hash map containing integer keys - @param name Name of the hash table [symbol] - @param khval_t Type of values [type] - */ -#define KHASH_MAP_INIT_INT(name, khval_t) \ - KHASH_INIT(name, khint32_t, khval_t, 1, kh_int_hash_func, kh_int_hash_equal) - -/*! @function - @abstract Instantiate a hash map containing 64-bit integer keys - @param name Name of the hash table [symbol] - */ -#define KHASH_SET_INIT_INT64(name) \ - KHASH_INIT(name, khint64_t, char, 0, kh_int64_hash_func, kh_int64_hash_equal) - -/*! @function - @abstract Instantiate a hash map containing 64-bit integer keys - @param name Name of the hash table [symbol] - @param khval_t Type of values [type] - */ -#define KHASH_MAP_INIT_INT64(name, khval_t) \ - KHASH_INIT(name, khint64_t, khval_t, 1, kh_int64_hash_func, kh_int64_hash_equal) - -typedef const char *kh_cstr_t; -/*! @function - @abstract Instantiate a hash map containing const char* keys - @param name Name of the hash table [symbol] - */ -#define KHASH_SET_INIT_STR(name) \ - KHASH_INIT(name, kh_cstr_t, char, 0, kh_str_hash_func, kh_str_hash_equal) - -/*! @function - @abstract Instantiate a hash map containing const char* keys - @param name Name of the hash table [symbol] - @param khval_t Type of values [type] - */ -#define KHASH_MAP_INIT_STR(name, khval_t) \ - KHASH_INIT(name, kh_cstr_t, khval_t, 1, kh_str_hash_func, kh_str_hash_equal) - -#endif /* __AC_KHASH_H */ diff --git a/web/server/h2o/libh2o/deps/klib/khmm.c b/web/server/h2o/libh2o/deps/klib/khmm.c deleted file mode 100644 index 711ade5a2..000000000 --- a/web/server/h2o/libh2o/deps/klib/khmm.c +++ /dev/null @@ -1,423 +0,0 @@ -#include <math.h> -#include <stdio.h> -#include <assert.h> -#include <string.h> -#include <stdlib.h> -#include "khmm.h" - -// new/delete hmm_par_t - -hmm_par_t *hmm_new_par(int m, int n) -{ - hmm_par_t *hp; - int i; - assert(m > 0 && n > 0); - hp = (hmm_par_t*)calloc(1, sizeof(hmm_par_t)); - hp->m = m; hp->n = n; - hp->a0 = (FLOAT*)calloc(n, sizeof(FLOAT)); - hp->a = (FLOAT**)calloc2(n, n, sizeof(FLOAT)); - hp->e = (FLOAT**)calloc2(m + 1, n, sizeof(FLOAT)); - hp->ae = (FLOAT**)calloc2((m + 1) * n, n, sizeof(FLOAT)); - for (i = 0; i != n; ++i) hp->e[m][i] = 1.0; - return hp; -} -void hmm_delete_par(hmm_par_t *hp) -{ - int i; - if (hp == 0) return; - for (i = 0; i != hp->n; ++i) free(hp->a[i]); - for (i = 0; i <= hp->m; ++i) free(hp->e[i]); - for (i = 0; i < (hp->m + 1) * hp->n; ++i) free(hp->ae[i]); - free(hp->a); free(hp->e); free(hp->a0); free(hp->ae); - free(hp); -} - -// new/delete hmm_data_t - -hmm_data_t *hmm_new_data(int L, const char *seq, const hmm_par_t *hp) -{ - hmm_data_t *hd; - hd = (hmm_data_t*)calloc(1, sizeof(hmm_data_t)); - hd->L = L; - hd->seq = (char*)malloc(L + 1); - memcpy(hd->seq + 1, seq, L); - return hd; -} -void hmm_delete_data(hmm_data_t *hd) -{ - int i; - if (hd == 0) return; - for (i = 0; i <= hd->L; ++i) { - if (hd->f) free(hd->f[i]); - if (hd->b) free(hd->b[i]); - } - free(hd->f); free(hd->b); free(hd->s); free(hd->v); free(hd->p); free(hd->seq); - free(hd); -} - -// new/delete hmm_exp_t - -hmm_exp_t *hmm_new_exp(const hmm_par_t *hp) -{ - hmm_exp_t *he; - assert(hp); - he = (hmm_exp_t*)calloc(1, sizeof(hmm_exp_t)); - he->m = hp->m; he->n = hp->n; - he->A0 = (FLOAT*)calloc(hp->n, sizeof(FLOAT)); - he->A = (FLOAT**)calloc2(hp->n, hp->n, sizeof(FLOAT)); - he->E = (FLOAT**)calloc2(hp->m + 1, hp->n, sizeof(FLOAT)); - return he; -} -void hmm_delete_exp(hmm_exp_t *he) -{ - int i; - if (he == 0) return; - for (i = 0; i != he->n; ++i) free(he->A[i]); - for (i = 0; i <= he->m; ++i) free(he->E[i]); - free(he->A); free(he->E); free(he->A0); - free(he); -} - -// Viterbi algorithm - -FLOAT hmm_Viterbi(const hmm_par_t *hp, hmm_data_t *hd) -{ - FLOAT **la, **le, *preV, *curV, max; - int **Vmax, max_l; // backtrace matrix - int k, l, b, u; - - if (hd->v) free(hd->v); - hd->v = (int*)calloc(hd->L+1, sizeof(int)); - la = (FLOAT**)calloc2(hp->n, hp->n, sizeof(FLOAT)); - le = (FLOAT**)calloc2(hp->m + 1, hp->n, sizeof(FLOAT)); - Vmax = (int**)calloc2(hd->L+1, hp->n, sizeof(int)); - preV = (FLOAT*)malloc(sizeof(FLOAT) * hp->n); - curV = (FLOAT*)malloc(sizeof(FLOAT) * hp->n); - for (k = 0; k != hp->n; ++k) - for (l = 0; l != hp->n; ++l) - la[k][l] = log(hp->a[l][k]); // this is not a bug - for (b = 0; b != hp->m; ++b) - for (k = 0; k != hp->n; ++k) - le[b][k] = log(hp->e[b][k]); - for (k = 0; k != hp->n; ++k) le[hp->m][k] = 0.0; - // V_k(1) - for (k = 0; k != hp->n; ++k) { - preV[k] = le[(int)hd->seq[1]][k] + log(hp->a0[k]); - Vmax[1][k] = 0; - } - // all the rest - for (u = 2; u <= hd->L; ++u) { - FLOAT *tmp, *leu = le[(int)hd->seq[u]]; - for (k = 0; k != hp->n; ++k) { - FLOAT *laa = la[k]; - for (l = 0, max = -HMM_INF, max_l = -1; l != hp->n; ++l) { - if (max < preV[l] + laa[l]) { - max = preV[l] + laa[l]; - max_l = l; - } - } - assert(max_l >= 0); // cannot be zero - curV[k] = leu[k] + max; - Vmax[u][k] = max_l; - } - tmp = curV; curV = preV; preV = tmp; // swap - } - // backtrace - for (k = 0, max_l = -1, max = -HMM_INF; k != hp->n; ++k) { - if (max < preV[k]) { - max = preV[k]; max_l = k; - } - } - assert(max_l >= 0); // cannot be zero - hd->v[hd->L] = max_l; - for (u = hd->L; u >= 1; --u) - hd->v[u-1] = Vmax[u][hd->v[u]]; - for (k = 0; k != hp->n; ++k) free(la[k]); - for (b = 0; b < hp->m; ++b) free(le[b]); - for (u = 0; u <= hd->L; ++u) free(Vmax[u]); - free(la); free(le); free(Vmax); free(preV); free(curV); - hd->status |= HMM_VITERBI; - return max; -} - -// forward algorithm - -void hmm_forward(const hmm_par_t *hp, hmm_data_t *hd) -{ - FLOAT sum, tmp, **at; - int u, k, l; - int n, m, L; - assert(hp && hd); - // allocate memory for hd->f and hd->s - n = hp->n; m = hp->m; L = hd->L; - if (hd->s) free(hd->s); - if (hd->f) { - for (k = 0; k <= hd->L; ++k) free(hd->f[k]); - free(hd->f); - } - hd->f = (FLOAT**)calloc2(hd->L+1, hp->n, sizeof(FLOAT)); - hd->s = (FLOAT*)calloc(hd->L+1, sizeof(FLOAT)); - hd->status &= ~(unsigned)HMM_FORWARD; - // at[][] array helps to improve the cache efficiency - at = (FLOAT**)calloc2(n, n, sizeof(FLOAT)); - // transpose a[][] - for (k = 0; k != n; ++k) - for (l = 0; l != n; ++l) - at[k][l] = hp->a[l][k]; - // f[0], but it should never be used - hd->s[0] = 1.0; - for (k = 0; k != n; ++k) hd->f[0][k] = 0.0; - // f[1] - for (k = 0, sum = 0.0; k != n; ++k) - sum += (hd->f[1][k] = hp->a0[k] * hp->e[(int)hd->seq[1]][k]); - for (k = 0; k != n; ++k) hd->f[1][k] /= sum; - hd->s[1] = sum; - // f[2..hmmL], the core loop - for (u = 2; u <= L; ++u) { - FLOAT *fu = hd->f[u], *fu1 = hd->f[u-1], *eu = hp->e[(int)hd->seq[u]]; - for (k = 0, sum = 0.0; k != n; ++k) { - FLOAT *aa = at[k]; - for (l = 0, tmp = 0.0; l != n; ++l) tmp += fu1[l] * aa[l]; - sum += (fu[k] = eu[k] * tmp); - } - for (k = 0; k != n; ++k) fu[k] /= sum; - hd->s[u] = sum; - } - // free at array - for (k = 0; k != hp->n; ++k) free(at[k]); - free(at); - hd->status |= HMM_FORWARD; -} - -// precalculate hp->ae - -void hmm_pre_backward(hmm_par_t *hp) -{ - int m, n, b, k, l; - assert(hp); - m = hp->m; n = hp->n; - for (b = 0; b <= m; ++b) { - for (k = 0; k != n; ++k) { - FLOAT *p = hp->ae[b * hp->n + k]; - for (l = 0; l != n; ++l) - p[l] = hp->e[b][l] * hp->a[k][l]; - } - } -} - -// backward algorithm - -void hmm_backward(const hmm_par_t *hp, hmm_data_t *hd) -{ - FLOAT tmp; - int k, l, u; - int m, n, L; - assert(hp && hd); - assert(hd->status & HMM_FORWARD); - // allocate memory for hd->b - m = hp->m; n = hp->n; L = hd->L; - if (hd->b) { - for (k = 0; k <= hd->L; ++k) free(hd->b[k]); - free(hd->b); - } - hd->status &= ~(unsigned)HMM_BACKWARD; - hd->b = (FLOAT**)calloc2(L+1, hp->n, sizeof(FLOAT)); - // b[L] - for (k = 0; k != hp->n; ++k) hd->b[L][k] = 1.0 / hd->s[L]; - // b[1..L-1], the core loop - for (u = L-1; u >= 1; --u) { - FLOAT *bu1 = hd->b[u+1], **p = hp->ae + (int)hd->seq[u+1] * n; - for (k = 0; k != n; ++k) { - FLOAT *q = p[k]; - for (l = 0, tmp = 0.0; l != n; ++l) tmp += q[l] * bu1[l]; - hd->b[u][k] = tmp / hd->s[u]; - } - } - hd->status |= HMM_BACKWARD; - for (l = 0, tmp = 0.0; l != n; ++l) - tmp += hp->a0[l] * hd->b[1][l] * hp->e[(int)hd->seq[1]][l]; - if (tmp > 1.0 + 1e-6 || tmp < 1.0 - 1e-6) // in theory, tmp should always equal to 1 - fprintf(stderr, "++ Underflow may have happened (%lg).\n", tmp); -} - -// log-likelihood of the observation - -FLOAT hmm_lk(const hmm_data_t *hd) -{ - FLOAT sum = 0.0, prod = 1.0; - int u, L; - L = hd->L; - assert(hd->status & HMM_FORWARD); - for (u = 1; u <= L; ++u) { - prod *= hd->s[u]; - if (prod < HMM_TINY || prod >= 1.0/HMM_TINY) { // reset - sum += log(prod); - prod = 1.0; - } - } - sum += log(prod); - return sum; -} - -// posterior decoding - -void hmm_post_decode(const hmm_par_t *hp, hmm_data_t *hd) -{ - int u, k; - assert(hd->status && HMM_BACKWARD); - if (hd->p) free(hd->p); - hd->p = (int*)calloc(hd->L + 1, sizeof(int)); - for (u = 1; u <= hd->L; ++u) { - FLOAT prob, max, *fu = hd->f[u], *bu = hd->b[u], su = hd->s[u]; - int max_k; - for (k = 0, max = -1.0, max_k = -1; k != hp->n; ++k) { - if (max < (prob = fu[k] * bu[k] * su)) { - max = prob; max_k = k; - } - } - assert(max_k >= 0); - hd->p[u] = max_k; - } - hd->status |= HMM_POSTDEC; -} - -// posterior probability of states - -FLOAT hmm_post_state(const hmm_par_t *hp, const hmm_data_t *hd, int u, FLOAT *prob) -{ - FLOAT sum = 0.0, ss = hd->s[u], *fu = hd->f[u], *bu = hd->b[u]; - int k; - for (k = 0; k != hp->n; ++k) - sum += (prob[k] = fu[k] * bu[k] * ss); - return sum; // in theory, this should always equal to 1.0 -} - -// expected counts - -hmm_exp_t *hmm_expect(const hmm_par_t *hp, const hmm_data_t *hd) -{ - int k, l, u, b, m, n; - hmm_exp_t *he; - assert(hd->status & HMM_BACKWARD); - he = hmm_new_exp(hp); - // initialization - m = hp->m; n = hp->n; - for (k = 0; k != n; ++k) - for (l = 0; l != n; ++l) he->A[k][l] = HMM_TINY; - for (b = 0; b <= m; ++b) - for (l = 0; l != n; ++l) he->E[b][l] = HMM_TINY; - // calculate A_{kl} and E_k(b), k,l\in[0,n) - for (u = 1; u < hd->L; ++u) { - FLOAT *fu = hd->f[u], *bu = hd->b[u], *bu1 = hd->b[u+1], ss = hd->s[u]; - FLOAT *Ec = he->E[(int)hd->seq[u]], **p = hp->ae + (int)hd->seq[u+1] * n; - for (k = 0; k != n; ++k) { - FLOAT *q = p[k], *AA = he->A[k], fuk = fu[k]; - for (l = 0; l != n; ++l) // this is cache-efficient - AA[l] += fuk * q[l] * bu1[l]; - Ec[k] += fuk * bu[k] * ss; - } - } - // calculate A0_l - for (l = 0; l != n; ++l) - he->A0[l] += hp->a0[l] * hp->e[(int)hd->seq[1]][l] * hd->b[1][l]; - return he; -} - -FLOAT hmm_Q0(const hmm_par_t *hp, hmm_exp_t *he) -{ - int k, l, b; - FLOAT sum = 0.0; - for (k = 0; k != hp->n; ++k) { - FLOAT tmp; - for (b = 0, tmp = 0.0; b != hp->m; ++b) tmp += he->E[b][k]; - for (b = 0; b != hp->m; ++b) - sum += he->E[b][k] * log(he->E[b][k] / tmp); - } - for (k = 0; k != hp->n; ++k) { - FLOAT tmp, *A = he->A[k]; - for (l = 0, tmp = 0.0; l != hp->n; ++l) tmp += A[l]; - for (l = 0; l != hp->n; ++l) sum += A[l] * log(A[l] / tmp); - } - return (he->Q0 = sum); -} - -// add he0 to he1 - -void hmm_add_expect(const hmm_exp_t *he0, hmm_exp_t *he1) -{ - int b, k, l; - assert(he0->m == he1->m && he0->n == he1->n); - for (k = 0; k != he1->n; ++k) { - he1->A0[k] += he0->A0[k]; - for (l = 0; l != he1->n; ++l) - he1->A[k][l] += he0->A[k][l]; - } - for (b = 0; b != he1->m; ++b) { - for (l = 0; l != he1->n; ++l) - he1->E[b][l] += he0->E[b][l]; - } -} - -// the EM-Q function - -FLOAT hmm_Q(const hmm_par_t *hp, const hmm_exp_t *he) -{ - FLOAT sum = 0.0; - int bb, k, l; - for (bb = 0; bb != he->m; ++bb) { - FLOAT *eb = hp->e[bb], *Eb = he->E[bb]; - for (k = 0; k != hp->n; ++k) { - if (eb[k] <= 0.0) return -HMM_INF; - sum += Eb[k] * log(eb[k]); - } - } - for (k = 0; k != he->n; ++k) { - FLOAT *Ak = he->A[k], *ak = hp->a[k]; - for (l = 0; l != he->n; ++l) { - if (ak[l] <= 0.0) return -HMM_INF; - sum += Ak[l] * log(ak[l]); - } - } - return (sum -= he->Q0); -} - -// simulate sequence - -char *hmm_simulate(const hmm_par_t *hp, int L) -{ - int i, k, l, b; - FLOAT x, y, **et; - char *seq; - seq = (char*)calloc(L+1, 1); - // calculate the transpose of hp->e[][] - et = (FLOAT**)calloc2(hp->n, hp->m, sizeof(FLOAT)); - for (k = 0; k != hp->n; ++k) - for (b = 0; b != hp->m; ++b) - et[k][b] = hp->e[b][k]; - // the initial state, drawn from a0[] - x = drand48(); - for (k = 0, y = 0.0; k != hp->n; ++k) { - y += hp->a0[k]; - if (y >= x) break; - } - // main loop - for (i = 0; i != L; ++i) { - FLOAT *el, *ak = hp->a[k]; - x = drand48(); - for (l = 0, y = 0.0; l != hp->n; ++l) { - y += ak[l]; - if (y >= x) break; - } - el = et[l]; - x = drand48(); - for (b = 0, y = 0.0; b != hp->m; ++b) { - y += el[b]; - if (y >= x) break; - } - seq[i] = b; - k = l; - } - for (k = 0; k != hp->n; ++k) free(et[k]); - free(et); - return seq; -} diff --git a/web/server/h2o/libh2o/deps/klib/khmm.h b/web/server/h2o/libh2o/deps/klib/khmm.h deleted file mode 100644 index d87673b93..000000000 --- a/web/server/h2o/libh2o/deps/klib/khmm.h +++ /dev/null @@ -1,107 +0,0 @@ -#ifndef AC_SCHMM_H_ -#define AC_SCHMM_H_ - -/* - * Last Modified: 2008-03-10 - * Version: 0.1.0-8 - * - * 2008-03-10, 0.1.0-8: make icc report two more "VECTORIZED" - * 2008-03-10, 0.1.0-7: accelerate for some CPU - * 2008-02-07, 0.1.0-6: simulate sequences - * 2008-01-15, 0.1.0-5: goodness of fit - * 2007-11-20, 0.1.0-4: add function declaration of hmm_post_decode() - * 2007-11-09: fix a memory leak - */ - -#include <stdlib.h> - -#define HMM_VERSION "0.1.0-7" - -#define HMM_FORWARD 0x02 -#define HMM_BACKWARD 0x04 -#define HMM_VITERBI 0x40 -#define HMM_POSTDEC 0x80 - -#ifndef FLOAT -#define FLOAT double -#endif -#define HMM_TINY 1e-25 -#define HMM_INF 1e300 - -typedef struct -{ - int m, n; // number of symbols, number of states - FLOAT **a, **e; // transition matrix and emitting probilities - FLOAT **ae; // auxiliary array for acceleration, should be calculated by hmm_pre_backward() - FLOAT *a0; // trasition matrix from the start state -} hmm_par_t; - -typedef struct -{ - int L; - unsigned status; - char *seq; - FLOAT **f, **b, *s; - int *v; // Viterbi path - int *p; // posterior decoding -} hmm_data_t; - -typedef struct -{ - int m, n; - FLOAT Q0, **A, **E, *A0; -} hmm_exp_t; - -typedef struct -{ - int l, *obs; - FLOAT *thr; -} hmm_gof_t; - -#ifdef __cplusplus -extern "C" { -#endif - /* initialize and destroy hmm_par_t */ - hmm_par_t *hmm_new_par(int m, int n); - void hmm_delete_par(hmm_par_t *hp); - /* initialize and destroy hmm_data_t */ - hmm_data_t *hmm_new_data(int L, const char *seq, const hmm_par_t *hp); - void hmm_delete_data(hmm_data_t *hd); - /* initialize and destroy hmm_exp_t */ - hmm_exp_t *hmm_new_exp(const hmm_par_t *hp); - void hmm_delete_exp(hmm_exp_t *he); - /* Viterbi, forward and backward algorithms */ - FLOAT hmm_Viterbi(const hmm_par_t *hp, hmm_data_t *hd); - void hmm_pre_backward(hmm_par_t *hp); - void hmm_forward(const hmm_par_t *hp, hmm_data_t *hd); - void hmm_backward(const hmm_par_t *hp, hmm_data_t *hd); - /* log-likelihood of the observations (natural based) */ - FLOAT hmm_lk(const hmm_data_t *hd); - /* posterior probability at the position on the sequence */ - FLOAT hmm_post_state(const hmm_par_t *hp, const hmm_data_t *hd, int u, FLOAT *prob); - /* posterior decoding */ - void hmm_post_decode(const hmm_par_t *hp, hmm_data_t *hd); - /* expected counts of transitions and emissions */ - hmm_exp_t *hmm_expect(const hmm_par_t *hp, const hmm_data_t *hd); - /* add he0 counts to he1 counts*/ - void hmm_add_expect(const hmm_exp_t *he0, hmm_exp_t *he1); - /* the Q function that should be maximized in EM */ - FLOAT hmm_Q(const hmm_par_t *hp, const hmm_exp_t *he); - FLOAT hmm_Q0(const hmm_par_t *hp, hmm_exp_t *he); - /* simulate sequences */ - char *hmm_simulate(const hmm_par_t *hp, int L); -#ifdef __cplusplus -} -#endif - -static inline void **calloc2(int n_row, int n_col, int size) -{ - char **p; - int k; - p = (char**)malloc(sizeof(char*) * n_row); - for (k = 0; k != n_row; ++k) - p[k] = (char*)calloc(n_col, size); - return (void**)p; -} - -#endif diff --git a/web/server/h2o/libh2o/deps/klib/klist.h b/web/server/h2o/libh2o/deps/klib/klist.h deleted file mode 100644 index 8b33f271e..000000000 --- a/web/server/h2o/libh2o/deps/klib/klist.h +++ /dev/null @@ -1,121 +0,0 @@ -/* The MIT License - - Copyright (c) 2008-2009, by Attractive Chaos <attractor@live.co.uk> - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. -*/ - -#ifndef _AC_KLIST_H -#define _AC_KLIST_H - -#include <stdlib.h> - -#define KMEMPOOL_INIT(name, kmptype_t, kmpfree_f) \ - typedef struct { \ - size_t cnt, n, max; \ - kmptype_t **buf; \ - } kmp_##name##_t; \ - static inline kmp_##name##_t *kmp_init_##name(void) { \ - return calloc(1, sizeof(kmp_##name##_t)); \ - } \ - static inline void kmp_destroy_##name(kmp_##name##_t *mp) { \ - size_t k; \ - for (k = 0; k < mp->n; ++k) { \ - kmpfree_f(mp->buf[k]); free(mp->buf[k]); \ - } \ - free(mp->buf); free(mp); \ - } \ - static inline kmptype_t *kmp_alloc_##name(kmp_##name##_t *mp) { \ - ++mp->cnt; \ - if (mp->n == 0) return calloc(1, sizeof(kmptype_t)); \ - return mp->buf[--mp->n]; \ - } \ - static inline void kmp_free_##name(kmp_##name##_t *mp, kmptype_t *p) { \ - --mp->cnt; \ - if (mp->n == mp->max) { \ - mp->max = mp->max? mp->max<<1 : 16; \ - mp->buf = realloc(mp->buf, sizeof(kmptype_t *) * mp->max); \ - } \ - mp->buf[mp->n++] = p; \ - } - -#define kmempool_t(name) kmp_##name##_t -#define kmp_init(name) kmp_init_##name() -#define kmp_destroy(name, mp) kmp_destroy_##name(mp) -#define kmp_alloc(name, mp) kmp_alloc_##name(mp) -#define kmp_free(name, mp, p) kmp_free_##name(mp, p) - -#define KLIST_INIT(name, kltype_t, kmpfree_t) \ - struct __kl1_##name { \ - kltype_t data; \ - struct __kl1_##name *next; \ - }; \ - typedef struct __kl1_##name kl1_##name; \ - KMEMPOOL_INIT(name, kl1_##name, kmpfree_t) \ - typedef struct { \ - kl1_##name *head, *tail; \ - kmp_##name##_t *mp; \ - size_t size; \ - } kl_##name##_t; \ - static inline kl_##name##_t *kl_init_##name(void) { \ - kl_##name##_t *kl = calloc(1, sizeof(kl_##name##_t)); \ - kl->mp = kmp_init(name); \ - kl->head = kl->tail = kmp_alloc(name, kl->mp); \ - kl->head->next = 0; \ - return kl; \ - } \ - static inline void kl_destroy_##name(kl_##name##_t *kl) { \ - kl1_##name *p; \ - for (p = kl->head; p != kl->tail; p = p->next) \ - kmp_free(name, kl->mp, p); \ - kmp_free(name, kl->mp, p); \ - kmp_destroy(name, kl->mp); \ - free(kl); \ - } \ - static inline kltype_t *kl_pushp_##name(kl_##name##_t *kl) { \ - kl1_##name *q, *p = kmp_alloc(name, kl->mp); \ - q = kl->tail; p->next = 0; kl->tail->next = p; kl->tail = p; \ - ++kl->size; \ - return &q->data; \ - } \ - static inline int kl_shift_##name(kl_##name##_t *kl, kltype_t *d) { \ - kl1_##name *p; \ - if (kl->head->next == 0) return -1; \ - --kl->size; \ - p = kl->head; kl->head = kl->head->next; \ - if (d) *d = p->data; \ - kmp_free(name, kl->mp, p); \ - return 0; \ - } - -#define kliter_t(name) kl1_##name -#define klist_t(name) kl_##name##_t -#define kl_val(iter) ((iter)->data) -#define kl_next(iter) ((iter)->next) -#define kl_begin(kl) ((kl)->head) -#define kl_end(kl) ((kl)->tail) - -#define kl_init(name) kl_init_##name() -#define kl_destroy(name, kl) kl_destroy_##name(kl) -#define kl_pushp(name, kl) kl_pushp_##name(kl) -#define kl_shift(name, kl, d) kl_shift_##name(kl, d) - -#endif diff --git a/web/server/h2o/libh2o/deps/klib/kmath.c b/web/server/h2o/libh2o/deps/klib/kmath.c deleted file mode 100644 index 9807b00ee..000000000 --- a/web/server/h2o/libh2o/deps/klib/kmath.c +++ /dev/null @@ -1,456 +0,0 @@ -#include <stdlib.h> -#include <string.h> -#include <math.h> -#include "kmath.h" - -/************************************** - *** Pseudo-random number generator *** - **************************************/ - -/* - 64-bit Mersenne Twister pseudorandom number generator. Adapted from: - - http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/VERSIONS/C-LANG/mt19937-64.c - - which was written by Takuji Nishimura and Makoto Matsumoto and released - under the 3-clause BSD license. -*/ - -#define KR_NN 312 -#define KR_MM 156 -#define KR_UM 0xFFFFFFFF80000000ULL /* Most significant 33 bits */ -#define KR_LM 0x7FFFFFFFULL /* Least significant 31 bits */ - -struct _krand_t { - int mti; - krint64_t mt[KR_NN]; -}; - -static void kr_srand0(krint64_t seed, krand_t *kr) -{ - kr->mt[0] = seed; - for (kr->mti = 1; kr->mti < KR_NN; ++kr->mti) - kr->mt[kr->mti] = 6364136223846793005ULL * (kr->mt[kr->mti - 1] ^ (kr->mt[kr->mti - 1] >> 62)) + kr->mti; -} - -krand_t *kr_srand(krint64_t seed) -{ - krand_t *kr; - kr = malloc(sizeof(krand_t)); - kr_srand0(seed, kr); - return kr; -} - -krint64_t kr_rand(krand_t *kr) -{ - krint64_t x; - static const krint64_t mag01[2] = { 0, 0xB5026F5AA96619E9ULL }; - if (kr->mti >= KR_NN) { - int i; - if (kr->mti == KR_NN + 1) kr_srand0(5489ULL, kr); - for (i = 0; i < KR_NN - KR_MM; ++i) { - x = (kr->mt[i] & KR_UM) | (kr->mt[i+1] & KR_LM); - kr->mt[i] = kr->mt[i + KR_MM] ^ (x>>1) ^ mag01[(int)(x&1)]; - } - for (; i < KR_NN - 1; ++i) { - x = (kr->mt[i] & KR_UM) | (kr->mt[i+1] & KR_LM); - kr->mt[i] = kr->mt[i + (KR_MM - KR_NN)] ^ (x>>1) ^ mag01[(int)(x&1)]; - } - x = (kr->mt[KR_NN - 1] & KR_UM) | (kr->mt[0] & KR_LM); - kr->mt[KR_NN - 1] = kr->mt[KR_MM - 1] ^ (x>>1) ^ mag01[(int)(x&1)]; - kr->mti = 0; - } - x = kr->mt[kr->mti++]; - x ^= (x >> 29) & 0x5555555555555555ULL; - x ^= (x << 17) & 0x71D67FFFEDA60000ULL; - x ^= (x << 37) & 0xFFF7EEE000000000ULL; - x ^= (x >> 43); - return x; -} - -#ifdef _KR_MAIN -int main(int argc, char *argv[]) -{ - long i, N = 200000000; - krand_t *kr; - if (argc > 1) N = atol(argv[1]); - kr = kr_srand(11); - for (i = 0; i < N; ++i) kr_rand(kr); -// for (i = 0; i < N; ++i) lrand48(); - free(kr); - return 0; -} -#endif - -/****************************** - *** Non-linear programming *** - ******************************/ - -/* Hooke-Jeeves algorithm for nonlinear minimization - - Based on the pseudocodes by Bell and Pike (CACM 9(9):684-685), and - the revision by Tomlin and Smith (CACM 12(11):637-638). Both of the - papers are comments on Kaupe's Algorithm 178 "Direct Search" (ACM - 6(6):313-314). The original algorithm was designed by Hooke and - Jeeves (ACM 8:212-229). This program is further revised according to - Johnson's implementation at Netlib (opt/hooke.c). - - Hooke-Jeeves algorithm is very simple and it works quite well on a - few examples. However, it might fail to converge due to its heuristic - nature. A possible improvement, as is suggested by Johnson, may be to - choose a small r at the beginning to quickly approach to the minimum - and a large r at later step to hit the minimum. - */ - -static double __kmin_hj_aux(kmin_f func, int n, double *x1, void *data, double fx1, double *dx, int *n_calls) -{ - int k, j = *n_calls; - double ftmp; - for (k = 0; k != n; ++k) { - x1[k] += dx[k]; - ftmp = func(n, x1, data); ++j; - if (ftmp < fx1) fx1 = ftmp; - else { /* search the opposite direction */ - dx[k] = 0.0 - dx[k]; - x1[k] += dx[k] + dx[k]; - ftmp = func(n, x1, data); ++j; - if (ftmp < fx1) fx1 = ftmp; - else x1[k] -= dx[k]; /* back to the original x[k] */ - } - } - *n_calls = j; - return fx1; /* here: fx1=f(n,x1) */ -} - -double kmin_hj(kmin_f func, int n, double *x, void *data, double r, double eps, int max_calls) -{ - double fx, fx1, *x1, *dx, radius; - int k, n_calls = 0; - x1 = (double*)calloc(n, sizeof(double)); - dx = (double*)calloc(n, sizeof(double)); - for (k = 0; k != n; ++k) { /* initial directions, based on MGJ */ - dx[k] = fabs(x[k]) * r; - if (dx[k] == 0) dx[k] = r; - } - radius = r; - fx1 = fx = func(n, x, data); ++n_calls; - for (;;) { - memcpy(x1, x, n * sizeof(double)); /* x1 = x */ - fx1 = __kmin_hj_aux(func, n, x1, data, fx, dx, &n_calls); - while (fx1 < fx) { - for (k = 0; k != n; ++k) { - double t = x[k]; - dx[k] = x1[k] > x[k]? fabs(dx[k]) : 0.0 - fabs(dx[k]); - x[k] = x1[k]; - x1[k] = x1[k] + x1[k] - t; - } - fx = fx1; - if (n_calls >= max_calls) break; - fx1 = func(n, x1, data); ++n_calls; - fx1 = __kmin_hj_aux(func, n, x1, data, fx1, dx, &n_calls); - if (fx1 >= fx) break; - for (k = 0; k != n; ++k) - if (fabs(x1[k] - x[k]) > .5 * fabs(dx[k])) break; - if (k == n) break; - } - if (radius >= eps) { - if (n_calls >= max_calls) break; - radius *= r; - for (k = 0; k != n; ++k) dx[k] *= r; - } else break; /* converge */ - } - free(x1); free(dx); - return fx1; -} - -// I copied this function somewhere several years ago with some of my modifications, but I forgot the source. -double kmin_brent(kmin1_f func, double a, double b, void *data, double tol, double *xmin) -{ - double bound, u, r, q, fu, tmp, fa, fb, fc, c; - const double gold1 = 1.6180339887; - const double gold2 = 0.3819660113; - const double tiny = 1e-20; - const int max_iter = 100; - - double e, d, w, v, mid, tol1, tol2, p, eold, fv, fw; - int iter; - - fa = func(a, data); fb = func(b, data); - if (fb > fa) { // swap, such that f(a) > f(b) - tmp = a; a = b; b = tmp; - tmp = fa; fa = fb; fb = tmp; - } - c = b + gold1 * (b - a), fc = func(c, data); // golden section extrapolation - while (fb > fc) { - bound = b + 100.0 * (c - b); // the farthest point where we want to go - r = (b - a) * (fb - fc); - q = (b - c) * (fb - fa); - if (fabs(q - r) < tiny) { // avoid 0 denominator - tmp = q > r? tiny : 0.0 - tiny; - } else tmp = q - r; - u = b - ((b - c) * q - (b - a) * r) / (2.0 * tmp); // u is the parabolic extrapolation point - if ((b > u && u > c) || (b < u && u < c)) { // u lies between b and c - fu = func(u, data); - if (fu < fc) { // (b,u,c) bracket the minimum - a = b; b = u; fa = fb; fb = fu; - break; - } else if (fu > fb) { // (a,b,u) bracket the minimum - c = u; fc = fu; - break; - } - u = c + gold1 * (c - b); fu = func(u, data); // golden section extrapolation - } else if ((c > u && u > bound) || (c < u && u < bound)) { // u lies between c and bound - fu = func(u, data); - if (fu < fc) { // fb > fc > fu - b = c; c = u; u = c + gold1 * (c - b); - fb = fc; fc = fu; fu = func(u, data); - } else { // (b,c,u) bracket the minimum - a = b; b = c; c = u; - fa = fb; fb = fc; fc = fu; - break; - } - } else if ((u > bound && bound > c) || (u < bound && bound < c)) { // u goes beyond the bound - u = bound; fu = func(u, data); - } else { // u goes the other way around, use golden section extrapolation - u = c + gold1 * (c - b); fu = func(u, data); - } - a = b; b = c; c = u; - fa = fb; fb = fc; fc = fu; - } - if (a > c) u = a, a = c, c = u; // swap - - // now, a<b<c, fa>fb and fb<fc, move on to Brent's algorithm - e = d = 0.0; - w = v = b; fv = fw = fb; - for (iter = 0; iter != max_iter; ++iter) { - mid = 0.5 * (a + c); - tol2 = 2.0 * (tol1 = tol * fabs(b) + tiny); - if (fabs(b - mid) <= (tol2 - 0.5 * (c - a))) { - *xmin = b; return fb; // found - } - if (fabs(e) > tol1) { - // related to parabolic interpolation - r = (b - w) * (fb - fv); - q = (b - v) * (fb - fw); - p = (b - v) * q - (b - w) * r; - q = 2.0 * (q - r); - if (q > 0.0) p = 0.0 - p; - else q = 0.0 - q; - eold = e; e = d; - if (fabs(p) >= fabs(0.5 * q * eold) || p <= q * (a - b) || p >= q * (c - b)) { - d = gold2 * (e = (b >= mid ? a - b : c - b)); - } else { - d = p / q; u = b + d; // actual parabolic interpolation happens here - if (u - a < tol2 || c - u < tol2) - d = (mid > b)? tol1 : 0.0 - tol1; - } - } else d = gold2 * (e = (b >= mid ? a - b : c - b)); // golden section interpolation - u = fabs(d) >= tol1 ? b + d : b + (d > 0.0? tol1 : -tol1); - fu = func(u, data); - if (fu <= fb) { // u is the minimum point so far - if (u >= b) a = b; - else c = b; - v = w; w = b; b = u; fv = fw; fw = fb; fb = fu; - } else { // adjust (a,c) and (u,v,w) - if (u < b) a = u; - else c = u; - if (fu <= fw || w == b) { - v = w; w = u; - fv = fw; fw = fu; - } else if (fu <= fv || v == b || v == w) { - v = u; fv = fu; - } - } - } - *xmin = b; - return fb; -} - -/************************* - *** Special functions *** - *************************/ - -/* Log gamma function - * \log{\Gamma(z)} - * AS245, 2nd algorithm, http://lib.stat.cmu.edu/apstat/245 - */ -double kf_lgamma(double z) -{ - double x = 0; - x += 0.1659470187408462e-06 / (z+7); - x += 0.9934937113930748e-05 / (z+6); - x -= 0.1385710331296526 / (z+5); - x += 12.50734324009056 / (z+4); - x -= 176.6150291498386 / (z+3); - x += 771.3234287757674 / (z+2); - x -= 1259.139216722289 / (z+1); - x += 676.5203681218835 / z; - x += 0.9999999999995183; - return log(x) - 5.58106146679532777 - z + (z-0.5) * log(z+6.5); -} - -/* complementary error function - * \frac{2}{\sqrt{\pi}} \int_x^{\infty} e^{-t^2} dt - * AS66, 2nd algorithm, http://lib.stat.cmu.edu/apstat/66 - */ -double kf_erfc(double x) -{ - const double p0 = 220.2068679123761; - const double p1 = 221.2135961699311; - const double p2 = 112.0792914978709; - const double p3 = 33.912866078383; - const double p4 = 6.37396220353165; - const double p5 = .7003830644436881; - const double p6 = .03526249659989109; - const double q0 = 440.4137358247522; - const double q1 = 793.8265125199484; - const double q2 = 637.3336333788311; - const double q3 = 296.5642487796737; - const double q4 = 86.78073220294608; - const double q5 = 16.06417757920695; - const double q6 = 1.755667163182642; - const double q7 = .08838834764831844; - double expntl, z, p; - z = fabs(x) * M_SQRT2; - if (z > 37.) return x > 0.? 0. : 2.; - expntl = exp(z * z * - .5); - if (z < 10. / M_SQRT2) // for small z - p = expntl * ((((((p6 * z + p5) * z + p4) * z + p3) * z + p2) * z + p1) * z + p0) - / (((((((q7 * z + q6) * z + q5) * z + q4) * z + q3) * z + q2) * z + q1) * z + q0); - else p = expntl / 2.506628274631001 / (z + 1. / (z + 2. / (z + 3. / (z + 4. / (z + .65))))); - return x > 0.? 2. * p : 2. * (1. - p); -} - -/* The following computes regularized incomplete gamma functions. - * Formulas are taken from Wiki, with additional input from Numerical - * Recipes in C (for modified Lentz's algorithm) and AS245 - * (http://lib.stat.cmu.edu/apstat/245). - * - * A good online calculator is available at: - * - * http://www.danielsoper.com/statcalc/calc23.aspx - * - * It calculates upper incomplete gamma function, which equals - * kf_gammaq(s,z)*tgamma(s). - */ - -#define KF_GAMMA_EPS 1e-14 -#define KF_TINY 1e-290 - -// regularized lower incomplete gamma function, by series expansion -static double _kf_gammap(double s, double z) -{ - double sum, x; - int k; - for (k = 1, sum = x = 1.; k < 100; ++k) { - sum += (x *= z / (s + k)); - if (x / sum < KF_GAMMA_EPS) break; - } - return exp(s * log(z) - z - kf_lgamma(s + 1.) + log(sum)); -} -// regularized upper incomplete gamma function, by continued fraction -static double _kf_gammaq(double s, double z) -{ - int j; - double C, D, f; - f = 1. + z - s; C = f; D = 0.; - // Modified Lentz's algorithm for computing continued fraction - // See Numerical Recipes in C, 2nd edition, section 5.2 - for (j = 1; j < 100; ++j) { - double a = j * (s - j), b = (j<<1) + 1 + z - s, d; - D = b + a * D; - if (D < KF_TINY) D = KF_TINY; - C = b + a / C; - if (C < KF_TINY) C = KF_TINY; - D = 1. / D; - d = C * D; - f *= d; - if (fabs(d - 1.) < KF_GAMMA_EPS) break; - } - return exp(s * log(z) - z - kf_lgamma(s) - log(f)); -} - -double kf_gammap(double s, double z) -{ - return z <= 1. || z < s? _kf_gammap(s, z) : 1. - _kf_gammaq(s, z); -} - -double kf_gammaq(double s, double z) -{ - return z <= 1. || z < s? 1. - _kf_gammap(s, z) : _kf_gammaq(s, z); -} - -/* Regularized incomplete beta function. The method is taken from - * Numerical Recipe in C, 2nd edition, section 6.4. The following web - * page calculates the incomplete beta function, which equals - * kf_betai(a,b,x) * gamma(a) * gamma(b) / gamma(a+b): - * - * http://www.danielsoper.com/statcalc/calc36.aspx - */ -static double kf_betai_aux(double a, double b, double x) -{ - double C, D, f; - int j; - if (x == 0.) return 0.; - if (x == 1.) return 1.; - f = 1.; C = f; D = 0.; - // Modified Lentz's algorithm for computing continued fraction - for (j = 1; j < 200; ++j) { - double aa, d; - int m = j>>1; - aa = (j&1)? -(a + m) * (a + b + m) * x / ((a + 2*m) * (a + 2*m + 1)) - : m * (b - m) * x / ((a + 2*m - 1) * (a + 2*m)); - D = 1. + aa * D; - if (D < KF_TINY) D = KF_TINY; - C = 1. + aa / C; - if (C < KF_TINY) C = KF_TINY; - D = 1. / D; - d = C * D; - f *= d; - if (fabs(d - 1.) < KF_GAMMA_EPS) break; - } - return exp(kf_lgamma(a+b) - kf_lgamma(a) - kf_lgamma(b) + a * log(x) + b * log(1.-x)) / a / f; -} -double kf_betai(double a, double b, double x) -{ - return x < (a + 1.) / (a + b + 2.)? kf_betai_aux(a, b, x) : 1. - kf_betai_aux(b, a, 1. - x); -} - -/****************** - *** Statistics *** - ******************/ - -double km_ks_dist(int na, const double a[], int nb, const double b[]) // a[] and b[] MUST BE sorted -{ - int ia = 0, ib = 0; - double fa = 0, fb = 0, sup = 0, na1 = 1. / na, nb1 = 1. / nb; - while (ia < na || ib < nb) { - if (ia == na) fb += nb1, ++ib; - else if (ib == nb) fa += na1, ++ia; - else if (a[ia] < b[ib]) fa += na1, ++ia; - else if (a[ia] > b[ib]) fb += nb1, ++ib; - else fa += na1, fb += nb1, ++ia, ++ib; - if (sup < fabs(fa - fb)) sup = fabs(fa - fb); - } - return sup; -} - -#ifdef KF_MAIN -#include <stdio.h> -#include "ksort.h" -KSORT_INIT_GENERIC(double) -int main(int argc, char *argv[]) -{ - double x = 5.5, y = 3; - double a, b; - double xx[] = {0.22, -0.87, -2.39, -1.79, 0.37, -1.54, 1.28, -0.31, -0.74, 1.72, 0.38, -0.17, -0.62, -1.10, 0.30, 0.15, 2.30, 0.19, -0.50, -0.09}; - double yy[] = {-5.13, -2.19, -2.43, -3.83, 0.50, -3.25, 4.32, 1.63, 5.18, -0.43, 7.11, 4.87, -3.10, -5.81, 3.76, 6.31, 2.58, 0.07, 5.76, 3.50}; - ks_introsort(double, 20, xx); ks_introsort(double, 20, yy); - printf("K-S distance: %f\n", km_ks_dist(20, xx, 20, yy)); - printf("erfc(%lg): %lg, %lg\n", x, erfc(x), kf_erfc(x)); - printf("upper-gamma(%lg,%lg): %lg\n", x, y, kf_gammaq(y, x)*tgamma(y)); - a = 2; b = 2; x = 0.5; - printf("incomplete-beta(%lg,%lg,%lg): %lg\n", a, b, x, kf_betai(a, b, x) / exp(kf_lgamma(a+b) - kf_lgamma(a) - kf_lgamma(b))); - return 0; -} -#endif diff --git a/web/server/h2o/libh2o/deps/klib/kmath.h b/web/server/h2o/libh2o/deps/klib/kmath.h deleted file mode 100644 index 2c3e77969..000000000 --- a/web/server/h2o/libh2o/deps/klib/kmath.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef AC_KMATH_H -#define AC_KMATH_H - -#include <stdint.h> - -#ifdef __cplusplus -extern "C" { -#endif - - /********************************** - * Pseudo-random number generator * - **********************************/ - - typedef uint64_t krint64_t; - - struct _krand_t; - typedef struct _krand_t krand_t; - - #define kr_drand(_kr) ((kr_rand(_kr) >> 11) * (1.0/9007199254740992.0)) - #define kr_sample(_kr, _k, _cnt) ((*(_cnt))++ < (_k)? *(_cnt) - 1 : kr_rand(_kr) % *(_cnt)) - - krand_t *kr_srand(krint64_t seed); - krint64_t kr_rand(krand_t *kr); - - /************************** - * Non-linear programming * - **************************/ - - #define KMIN_RADIUS 0.5 - #define KMIN_EPS 1e-7 - #define KMIN_MAXCALL 50000 - - typedef double (*kmin_f)(int, double*, void*); - typedef double (*kmin1_f)(double, void*); - - double kmin_hj(kmin_f func, int n, double *x, void *data, double r, double eps, int max_calls); // Hooke-Jeeves' - double kmin_brent(kmin1_f func, double a, double b, void *data, double tol, double *xmin); // Brent's 1-dimenssion - - /********************* - * Special functions * - *********************/ - - double kf_lgamma(double z); // log gamma function - double kf_erfc(double x); // complementary error function - double kf_gammap(double s, double z); // regularized lower incomplete gamma function - double kf_gammaq(double s, double z); // regularized upper incomplete gamma function - double kf_betai(double a, double b, double x); // regularized incomplete beta function - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/web/server/h2o/libh2o/deps/klib/knetfile.c b/web/server/h2o/libh2o/deps/klib/knetfile.c deleted file mode 100644 index 158add911..000000000 --- a/web/server/h2o/libh2o/deps/klib/knetfile.c +++ /dev/null @@ -1,628 +0,0 @@ -/* The MIT License - - Copyright (c) 2008 by Genome Research Ltd (GRL). - 2010 by Attractive Chaos <attractor@live.co.uk> - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. -*/ - -/* Probably I will not do socket programming in the next few years and - therefore I decide to heavily annotate this file, for Linux and - Windows as well. -ac */ - -#include <time.h> -#include <stdio.h> -#include <ctype.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <sys/types.h> - -#ifndef _WIN32 -#include <netdb.h> -#include <arpa/inet.h> -#include <sys/socket.h> -#endif - -#include "knetfile.h" - -/* In winsock.h, the type of a socket is SOCKET, which is: "typedef - * u_int SOCKET". An invalid SOCKET is: "(SOCKET)(~0)", or signed - * integer -1. In knetfile.c, I use "int" for socket type - * throughout. This should be improved to avoid confusion. - * - * In Linux/Mac, recv() and read() do almost the same thing. You can see - * in the header file that netread() is simply an alias of read(). In - * Windows, however, they are different and using recv() is mandatory. - */ - -/* This function tests if the file handler is ready for reading (or - * writing if is_read==0). */ -static int socket_wait(int fd, int is_read) -{ - fd_set fds, *fdr = 0, *fdw = 0; - struct timeval tv; - int ret; - tv.tv_sec = 5; tv.tv_usec = 0; // 5 seconds time out - FD_ZERO(&fds); - FD_SET(fd, &fds); - if (is_read) fdr = &fds; - else fdw = &fds; - ret = select(fd+1, fdr, fdw, 0, &tv); -#ifndef _WIN32 - if (ret == -1) perror("select"); -#else - if (ret == 0) - fprintf(stderr, "select time-out\n"); - else if (ret == SOCKET_ERROR) - fprintf(stderr, "select: %d\n", WSAGetLastError()); -#endif - return ret; -} - -#ifndef _WIN32 -/* This function does not work with Windows due to the lack of - * getaddrinfo() in winsock. It is addapted from an example in "Beej's - * Guide to Network Programming" (http://beej.us/guide/bgnet/). */ -static int socket_connect(const char *host, const char *port) -{ -#define __err_connect(func) do { perror(func); freeaddrinfo(res); return -1; } while (0) - - int on = 1, fd; - struct linger lng = { 0, 0 }; - struct addrinfo hints, *res = 0; - memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - /* In Unix/Mac, getaddrinfo() is the most convenient way to get - * server information. */ - if (getaddrinfo(host, port, &hints, &res) != 0) __err_connect("getaddrinfo"); - if ((fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1) __err_connect("socket"); - /* The following two setsockopt() are used by ftplib - * (http://nbpfaus.net/~pfau/ftplib/). I am not sure if they - * necessary. */ - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) __err_connect("setsockopt"); - if (setsockopt(fd, SOL_SOCKET, SO_LINGER, &lng, sizeof(lng)) == -1) __err_connect("setsockopt"); - if (connect(fd, res->ai_addr, res->ai_addrlen) != 0) __err_connect("connect"); - freeaddrinfo(res); - return fd; -} -#else -/* MinGW's printf has problem with "%lld" */ -char *int64tostr(char *buf, int64_t x) -{ - int cnt; - int i = 0; - do { - buf[i++] = '0' + x % 10; - x /= 10; - } while (x); - buf[i] = 0; - for (cnt = i, i = 0; i < cnt/2; ++i) { - int c = buf[i]; buf[i] = buf[cnt-i-1]; buf[cnt-i-1] = c; - } - return buf; -} - -int64_t strtoint64(const char *buf) -{ - int64_t x; - for (x = 0; *buf != '\0'; ++buf) - x = x * 10 + ((int64_t) *buf - 48); - return x; -} -/* In windows, the first thing is to establish the TCP connection. */ -int knet_win32_init() -{ - WSADATA wsaData; - return WSAStartup(MAKEWORD(2, 2), &wsaData); -} -void knet_win32_destroy() -{ - WSACleanup(); -} -/* A slightly modfied version of the following function also works on - * Mac (and presummably Linux). However, this function is not stable on - * my Mac. It sometimes works fine but sometimes does not. Therefore for - * non-Windows OS, I do not use this one. */ -static SOCKET socket_connect(const char *host, const char *port) -{ -#define __err_connect(func) \ - do { \ - fprintf(stderr, "%s: %d\n", func, WSAGetLastError()); \ - return -1; \ - } while (0) - - int on = 1; - SOCKET fd; - struct linger lng = { 0, 0 }; - struct sockaddr_in server; - struct hostent *hp = 0; - // open socket - if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) __err_connect("socket"); - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on)) == -1) __err_connect("setsockopt"); - if (setsockopt(fd, SOL_SOCKET, SO_LINGER, (char*)&lng, sizeof(lng)) == -1) __err_connect("setsockopt"); - // get host info - if (isalpha(host[0])) hp = gethostbyname(host); - else { - struct in_addr addr; - addr.s_addr = inet_addr(host); - hp = gethostbyaddr((char*)&addr, 4, AF_INET); - } - if (hp == 0) __err_connect("gethost"); - // connect - server.sin_addr.s_addr = *((unsigned long*)hp->h_addr); - server.sin_family= AF_INET; - server.sin_port = htons(atoi(port)); - if (connect(fd, (struct sockaddr*)&server, sizeof(server)) != 0) __err_connect("connect"); - // freehostent(hp); // strangely in MSDN, hp is NOT freed (memory leak?!) - return fd; -} -#endif - -static off_t my_netread(int fd, void *buf, off_t len) -{ - off_t rest = len, curr, l = 0; - /* recv() and read() may not read the required length of data with - * one call. They have to be called repeatedly. */ - while (rest) { - if (socket_wait(fd, 1) <= 0) break; // socket is not ready for reading - curr = netread(fd, buf + l, rest); - /* According to the glibc manual, section 13.2, a zero returned - * value indicates end-of-file (EOF), which should mean that - * read() will not return zero if EOF has not been met but data - * are not immediately available. */ - if (curr == 0) break; - l += curr; rest -= curr; - } - return l; -} - -/************************* - * FTP specific routines * - *************************/ - -static int kftp_get_response(knetFile *ftp) -{ -#ifndef _WIN32 - unsigned char c; -#else - char c; -#endif - int n = 0; - char *p; - if (socket_wait(ftp->ctrl_fd, 1) <= 0) return 0; - while (netread(ftp->ctrl_fd, &c, 1)) { // FIXME: this is *VERY BAD* for unbuffered I/O - //fputc(c, stderr); - if (n >= ftp->max_response) { - ftp->max_response = ftp->max_response? ftp->max_response<<1 : 256; - ftp->response = (char*)realloc(ftp->response, ftp->max_response); - } - ftp->response[n++] = c; - if (c == '\n') { - if (n >= 4 && isdigit(ftp->response[0]) && isdigit(ftp->response[1]) && isdigit(ftp->response[2]) - && ftp->response[3] != '-') break; - n = 0; - continue; - } - } - if (n < 2) return -1; - ftp->response[n-2] = 0; - return strtol(ftp->response, &p, 0); -} - -static int kftp_send_cmd(knetFile *ftp, const char *cmd, int is_get) -{ - if (socket_wait(ftp->ctrl_fd, 0) <= 0) return -1; // socket is not ready for writing - netwrite(ftp->ctrl_fd, cmd, strlen(cmd)); - return is_get? kftp_get_response(ftp) : 0; -} - -static int kftp_pasv_prep(knetFile *ftp) -{ - char *p; - int v[6]; - kftp_send_cmd(ftp, "PASV\r\n", 1); - for (p = ftp->response; *p && *p != '('; ++p); - if (*p != '(') return -1; - ++p; - sscanf(p, "%d,%d,%d,%d,%d,%d", &v[0], &v[1], &v[2], &v[3], &v[4], &v[5]); - memcpy(ftp->pasv_ip, v, 4 * sizeof(int)); - ftp->pasv_port = (v[4]<<8&0xff00) + v[5]; - return 0; -} - - -static int kftp_pasv_connect(knetFile *ftp) -{ - char host[80], port[10]; - if (ftp->pasv_port == 0) { - fprintf(stderr, "[kftp_pasv_connect] kftp_pasv_prep() is not called before hand.\n"); - return -1; - } - sprintf(host, "%d.%d.%d.%d", ftp->pasv_ip[0], ftp->pasv_ip[1], ftp->pasv_ip[2], ftp->pasv_ip[3]); - sprintf(port, "%d", ftp->pasv_port); - ftp->fd = socket_connect(host, port); - if (ftp->fd == -1) return -1; - return 0; -} - -int kftp_connect(knetFile *ftp) -{ - ftp->ctrl_fd = socket_connect(ftp->host, ftp->port); - if (ftp->ctrl_fd == -1) return -1; - kftp_get_response(ftp); - kftp_send_cmd(ftp, "USER anonymous\r\n", 1); - kftp_send_cmd(ftp, "PASS kftp@\r\n", 1); - kftp_send_cmd(ftp, "TYPE I\r\n", 1); - return 0; -} - -int kftp_reconnect(knetFile *ftp) -{ - if (ftp->ctrl_fd != -1) { - netclose(ftp->ctrl_fd); - ftp->ctrl_fd = -1; - } - netclose(ftp->fd); - ftp->fd = -1; - return kftp_connect(ftp); -} - -// initialize ->type, ->host, ->retr and ->size -knetFile *kftp_parse_url(const char *fn, const char *mode) -{ - knetFile *fp; - char *p; - int l; - if (strstr(fn, "ftp://") != fn) return 0; - for (p = (char*)fn + 6; *p && *p != '/'; ++p); - if (*p != '/') return 0; - l = p - fn - 6; - fp = (knetFile*)calloc(1, sizeof(knetFile)); - fp->type = KNF_TYPE_FTP; - fp->fd = -1; - /* the Linux/Mac version of socket_connect() also recognizes a port - * like "ftp", but the Windows version does not. */ - fp->port = strdup("21"); - fp->host = (char*)calloc(l + 1, 1); - if (strchr(mode, 'c')) fp->no_reconnect = 1; - strncpy(fp->host, fn + 6, l); - fp->retr = (char*)calloc(strlen(p) + 8, 1); - sprintf(fp->retr, "RETR %s\r\n", p); - fp->size_cmd = (char*)calloc(strlen(p) + 8, 1); - sprintf(fp->size_cmd, "SIZE %s\r\n", p); - fp->seek_offset = 0; - return fp; -} -// place ->fd at offset off -int kftp_connect_file(knetFile *fp) -{ - int ret; - long long file_size; - if (fp->fd != -1) { - netclose(fp->fd); - if (fp->no_reconnect) kftp_get_response(fp); - } - kftp_pasv_prep(fp); - kftp_send_cmd(fp, fp->size_cmd, 1); -#ifndef _WIN32 - if ( sscanf(fp->response,"%*d %lld", &file_size) != 1 ) - { - fprintf(stderr,"[kftp_connect_file] %s\n", fp->response); - return -1; - } -#else - const char *p = fp->response; - while (*p != ' ') ++p; - while (*p < '0' || *p > '9') ++p; - file_size = strtoint64(p); -#endif - fp->file_size = file_size; - if (fp->offset>=0) { - char tmp[32]; -#ifndef _WIN32 - sprintf(tmp, "REST %lld\r\n", (long long)fp->offset); -#else - strcpy(tmp, "REST "); - int64tostr(tmp + 5, fp->offset); - strcat(tmp, "\r\n"); -#endif - kftp_send_cmd(fp, tmp, 1); - } - kftp_send_cmd(fp, fp->retr, 0); - kftp_pasv_connect(fp); - ret = kftp_get_response(fp); - if (ret != 150) { - fprintf(stderr, "[kftp_connect_file] %s\n", fp->response); - netclose(fp->fd); - fp->fd = -1; - return -1; - } - fp->is_ready = 1; - return 0; -} - - -/************************** - * HTTP specific routines * - **************************/ - -knetFile *khttp_parse_url(const char *fn, const char *mode) -{ - knetFile *fp; - char *p, *proxy, *q; - int l; - if (strstr(fn, "http://") != fn) return 0; - // set ->http_host - for (p = (char*)fn + 7; *p && *p != '/'; ++p); - l = p - fn - 7; - fp = (knetFile*)calloc(1, sizeof(knetFile)); - fp->http_host = (char*)calloc(l + 1, 1); - strncpy(fp->http_host, fn + 7, l); - fp->http_host[l] = 0; - for (q = fp->http_host; *q && *q != ':'; ++q); - if (*q == ':') *q++ = 0; - // get http_proxy - proxy = getenv("http_proxy"); - // set ->host, ->port and ->path - if (proxy == 0) { - fp->host = strdup(fp->http_host); // when there is no proxy, server name is identical to http_host name. - fp->port = strdup(*q? q : "80"); - fp->path = strdup(*p? p : "/"); - } else { - fp->host = (strstr(proxy, "http://") == proxy)? strdup(proxy + 7) : strdup(proxy); - for (q = fp->host; *q && *q != ':'; ++q); - if (*q == ':') *q++ = 0; - fp->port = strdup(*q? q : "80"); - fp->path = strdup(fn); - } - fp->type = KNF_TYPE_HTTP; - fp->ctrl_fd = fp->fd = -1; - fp->seek_offset = 0; - return fp; -} - -int khttp_connect_file(knetFile *fp) -{ - int ret, l = 0; - char *buf, *p; - if (fp->fd != -1) netclose(fp->fd); - fp->fd = socket_connect(fp->host, fp->port); - buf = (char*)calloc(0x10000, 1); // FIXME: I am lazy... But in principle, 64KB should be large enough. - l += sprintf(buf + l, "GET %s HTTP/1.0\r\nHost: %s\r\n", fp->path, fp->http_host); - l += sprintf(buf + l, "Range: bytes=%lld-\r\n", (long long)fp->offset); - l += sprintf(buf + l, "\r\n"); - netwrite(fp->fd, buf, l); - l = 0; - while (netread(fp->fd, buf + l, 1)) { // read HTTP header; FIXME: bad efficiency - if (buf[l] == '\n' && l >= 3) - if (strncmp(buf + l - 3, "\r\n\r\n", 4) == 0) break; - ++l; - } - buf[l] = 0; - if (l < 14) { // prematured header - netclose(fp->fd); - fp->fd = -1; - return -1; - } - ret = strtol(buf + 8, &p, 0); // HTTP return code - if (ret == 200 && fp->offset>0) { // 200 (complete result); then skip beginning of the file - off_t rest = fp->offset; - while (rest) { - off_t l = rest < 0x10000? rest : 0x10000; - rest -= my_netread(fp->fd, buf, l); - } - } else if (ret != 206 && ret != 200) { - free(buf); - fprintf(stderr, "[khttp_connect_file] fail to open file (HTTP code: %d).\n", ret); - netclose(fp->fd); - fp->fd = -1; - return -1; - } - free(buf); - fp->is_ready = 1; - return 0; -} - -/******************** - * Generic routines * - ********************/ - -knetFile *knet_open(const char *fn, const char *mode) -{ - knetFile *fp = 0; - if (mode[0] != 'r') { - fprintf(stderr, "[kftp_open] only mode \"r\" is supported.\n"); - return 0; - } - if (strstr(fn, "ftp://") == fn) { - fp = kftp_parse_url(fn, mode); - if (fp == 0) return 0; - if (kftp_connect(fp) == -1) { - knet_close(fp); - return 0; - } - kftp_connect_file(fp); - } else if (strstr(fn, "http://") == fn) { - fp = khttp_parse_url(fn, mode); - if (fp == 0) return 0; - khttp_connect_file(fp); - } else { // local file -#ifdef _WIN32 - /* In windows, O_BINARY is necessary. In Linux/Mac, O_BINARY may - * be undefined on some systems, although it is defined on my - * Mac and the Linux I have tested on. */ - int fd = open(fn, O_RDONLY | O_BINARY); -#else - int fd = open(fn, O_RDONLY); -#endif - if (fd == -1) { - perror("open"); - return 0; - } - fp = (knetFile*)calloc(1, sizeof(knetFile)); - fp->type = KNF_TYPE_LOCAL; - fp->fd = fd; - fp->ctrl_fd = -1; - } - if (fp && fp->fd == -1) { - knet_close(fp); - return 0; - } - return fp; -} - -knetFile *knet_dopen(int fd, const char *mode) -{ - knetFile *fp = (knetFile*)calloc(1, sizeof(knetFile)); - fp->type = KNF_TYPE_LOCAL; - fp->fd = fd; - return fp; -} - -off_t knet_read(knetFile *fp, void *buf, off_t len) -{ - off_t l = 0; - if (fp->fd == -1) return 0; - if (fp->type == KNF_TYPE_FTP) { - if (fp->is_ready == 0) { - if (!fp->no_reconnect) kftp_reconnect(fp); - kftp_connect_file(fp); - } - } else if (fp->type == KNF_TYPE_HTTP) { - if (fp->is_ready == 0) - khttp_connect_file(fp); - } - if (fp->type == KNF_TYPE_LOCAL) { // on Windows, the following block is necessary; not on UNIX - off_t rest = len, curr; - while (rest) { - do { - curr = read(fp->fd, buf + l, rest); - } while (curr < 0 && EINTR == errno); - if (curr < 0) return -1; - if (curr == 0) break; - l += curr; rest -= curr; - } - } else l = my_netread(fp->fd, buf, len); - fp->offset += l; - return l; -} - -off_t knet_seek(knetFile *fp, int64_t off, int whence) -{ - if (whence == SEEK_SET && off == fp->offset) return 0; - if (fp->type == KNF_TYPE_LOCAL) { - /* Be aware that lseek() returns the offset after seeking, - * while fseek() returns zero on success. */ - off_t offset = lseek(fp->fd, off, whence); - if (offset == -1) { - // Be silent, it is OK for knet_seek to fail when the file is streamed - // fprintf(stderr,"[knet_seek] %s\n", strerror(errno)); - return -1; - } - fp->offset = offset; - return off; - } else if (fp->type == KNF_TYPE_FTP) { - if (whence==SEEK_CUR) - fp->offset += off; - else if (whence==SEEK_SET) - fp->offset = off; - else if ( whence==SEEK_END) - fp->offset = fp->file_size+off; - fp->is_ready = 0; - return off; - } else if (fp->type == KNF_TYPE_HTTP) { - if (whence == SEEK_END) { // FIXME: can we allow SEEK_END in future? - fprintf(stderr, "[knet_seek] SEEK_END is not supported for HTTP. Offset is unchanged.\n"); - errno = ESPIPE; - return -1; - } - if (whence==SEEK_CUR) - fp->offset += off; - else if (whence==SEEK_SET) - fp->offset = off; - fp->is_ready = 0; - return off; - } - errno = EINVAL; - fprintf(stderr,"[knet_seek] %s\n", strerror(errno)); - return -1; -} - -int knet_close(knetFile *fp) -{ - if (fp == 0) return 0; - if (fp->ctrl_fd != -1) netclose(fp->ctrl_fd); // FTP specific - if (fp->fd != -1) { - /* On Linux/Mac, netclose() is an alias of close(), but on - * Windows, it is an alias of closesocket(). */ - if (fp->type == KNF_TYPE_LOCAL) close(fp->fd); - else netclose(fp->fd); - } - free(fp->host); free(fp->port); - free(fp->response); free(fp->retr); // FTP specific - free(fp->path); free(fp->http_host); // HTTP specific - free(fp); - return 0; -} - -#ifdef KNETFILE_MAIN -int main(void) -{ - char *buf; - knetFile *fp; - int type = 4, l; -#ifdef _WIN32 - knet_win32_init(); -#endif - buf = calloc(0x100000, 1); - if (type == 0) { - fp = knet_open("knetfile.c", "r"); - knet_seek(fp, 1000, SEEK_SET); - } else if (type == 1) { // NCBI FTP, large file - fp = knet_open("ftp://ftp.ncbi.nih.gov/1000genomes/ftp/data/NA12878/alignment/NA12878.chrom6.SLX.SRP000032.2009_06.bam", "r"); - knet_seek(fp, 2500000000ll, SEEK_SET); - l = knet_read(fp, buf, 255); - } else if (type == 2) { - fp = knet_open("ftp://ftp.sanger.ac.uk/pub4/treefam/tmp/index.shtml", "r"); - knet_seek(fp, 1000, SEEK_SET); - } else if (type == 3) { - fp = knet_open("http://www.sanger.ac.uk/Users/lh3/index.shtml", "r"); - knet_seek(fp, 1000, SEEK_SET); - } else if (type == 4) { - fp = knet_open("http://www.sanger.ac.uk/Users/lh3/ex1.bam", "r"); - knet_read(fp, buf, 10000); - knet_seek(fp, 20000, SEEK_SET); - knet_seek(fp, 10000, SEEK_SET); - l = knet_read(fp, buf+10000, 10000000) + 10000; - } - if (type != 4 && type != 1) { - knet_read(fp, buf, 255); - buf[255] = 0; - printf("%s\n", buf); - } else write(fileno(stdout), buf, l); - knet_close(fp); - free(buf); - return 0; -} -#endif diff --git a/web/server/h2o/libh2o/deps/klib/knetfile.h b/web/server/h2o/libh2o/deps/klib/knetfile.h deleted file mode 100644 index 0a0e66f7a..000000000 --- a/web/server/h2o/libh2o/deps/klib/knetfile.h +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef KNETFILE_H -#define KNETFILE_H - -#include <stdint.h> -#include <fcntl.h> - -#ifndef _WIN32 -#define netread(fd, ptr, len) read(fd, ptr, len) -#define netwrite(fd, ptr, len) write(fd, ptr, len) -#define netclose(fd) close(fd) -#else -#include <winsock2.h> -#define netread(fd, ptr, len) recv(fd, ptr, len, 0) -#define netwrite(fd, ptr, len) send(fd, ptr, len, 0) -#define netclose(fd) closesocket(fd) -#endif - -// FIXME: currently I/O is unbuffered - -#define KNF_TYPE_LOCAL 1 -#define KNF_TYPE_FTP 2 -#define KNF_TYPE_HTTP 3 - -typedef struct knetFile_s { - int type, fd; - int64_t offset; - char *host, *port; - - // the following are for FTP only - int ctrl_fd, pasv_ip[4], pasv_port, max_response, no_reconnect, is_ready; - char *response, *retr, *size_cmd; - int64_t seek_offset; // for lazy seek - int64_t file_size; - - // the following are for HTTP only - char *path, *http_host; -} knetFile; - -#define knet_tell(fp) ((fp)->offset) -#define knet_fileno(fp) ((fp)->fd) - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef _WIN32 - int knet_win32_init(); - void knet_win32_destroy(); -#endif - - knetFile *knet_open(const char *fn, const char *mode); - - /* - This only works with local files. - */ - knetFile *knet_dopen(int fd, const char *mode); - - /* - If ->is_ready==0, this routine updates ->fd; otherwise, it simply - reads from ->fd. - */ - off_t knet_read(knetFile *fp, void *buf, off_t len); - - /* - This routine only sets ->offset and ->is_ready=0. It does not - communicate with the FTP server. - */ - off_t knet_seek(knetFile *fp, int64_t off, int whence); - int knet_close(knetFile *fp); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/web/server/h2o/libh2o/deps/klib/knhx.c b/web/server/h2o/libh2o/deps/klib/knhx.c deleted file mode 100644 index 8dbd3b6e3..000000000 --- a/web/server/h2o/libh2o/deps/klib/knhx.c +++ /dev/null @@ -1,166 +0,0 @@ -#include <ctype.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include "knhx.h" - -typedef struct { - int error, n, max; - knhx1_t *node; -} knaux_t; - -static inline char *add_node(const char *s, knaux_t *aux, int x) -{ - char *p, *nbeg, *nend = 0; - knhx1_t *r; - if (aux->n == aux->max) { - aux->max = aux->max? aux->max<<1 : 8; - aux->node = (knhx1_t*)realloc(aux->node, sizeof(knhx1_t) * aux->max); - } - r = aux->node + (aux->n++); - r->n = x; r->parent = -1; - for (p = (char*)s, nbeg = p, r->d = -1.0; *p && *p != ',' && *p != ')'; ++p) { - if (*p == '[') { - if (nend == 0) nend = p; - do ++p; while (*p && *p != ']'); - if (*p == 0) { - aux->error |= KNERR_BRACKET; - break; - } - } else if (*p == ':') { - if (nend == 0) nend = p; - r->d = strtod(p + 1, &p); - --p; - } else if (!isgraph(*p)) if (nend == 0) nend = p; - } - if (nend == 0) nend = p; - if (nend != nbeg) { - r->name = (char*)calloc(nend - nbeg + 1, 1); - strncpy(r->name, nbeg, nend - nbeg); - } else r->name = strdup(""); - return p; -} - -knhx1_t *kn_parse(const char *nhx, int *_n, int *_error) -{ - char *p; - int *stack, top, max; - knaux_t *aux; - knhx1_t *ret; - -#define __push_back(y) do { \ - if (top == max) { \ - max = max? max<<1 : 16; \ - stack = (int*)realloc(stack, sizeof(int) * max); \ - } \ - stack[top++] = (y); \ - } while (0) \ - - stack = 0; top = max = 0; - p = (char*)nhx; - aux = (knaux_t*)calloc(1, sizeof(knaux_t)); - while (*p) { - while (*p && !isgraph(*p)) ++p; - if (*p == 0) break; - if (*p == ',') ++p; - else if (*p == '(') { - __push_back(-1); - ++p; - } else if (*p == ')') { - int x = aux->n, m, i; - for (i = top - 1; i >= 0; --i) - if (stack[i] < 0) break; - m = top - 1 - i; - p = add_node(p + 1, aux, m); - aux->node[x].child = (int*)calloc(m, sizeof(int)); - for (i = top - 1, m = m - 1; m >= 0; --m, --i) { - aux->node[x].child[m] = stack[i]; - aux->node[stack[i]].parent = x; - } - top = i; - __push_back(x); - } else { - __push_back(aux->n); - p = add_node(p, aux, 0); - } - } - *_n = aux->n; - *_error = aux->error; - ret = aux->node; - free(aux); free(stack); - return ret; -} - -#ifndef kroundup32 -#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) -#endif - -static inline int kputsn(const char *p, int l, kstring_t *s) -{ - if (s->l + l + 1 >= s->m) { - s->m = s->l + l + 2; - kroundup32(s->m); - s->s = (char*)realloc(s->s, s->m); - } - memcpy(s->s + s->l, p, l); - s->l += l; s->s[s->l] = 0; - return l; -} - -static inline int kputc(int c, kstring_t *s) -{ - if (s->l + 1 >= s->m) { - s->m = s->l + 2; - kroundup32(s->m); - s->s = (char*)realloc(s->s, s->m); - } - s->s[s->l++] = c; s->s[s->l] = 0; - return c; -} - -static void format_node_recur(const knhx1_t *node, const knhx1_t *p, kstring_t *s, char *numbuf) -{ - if (p->n) { - int i; - kputc('(', s); - for (i = 0; i < p->n; ++i) { - if (i) kputc(',', s); - format_node_recur(node, &node[p->child[i]], s, numbuf); - } - kputc(')', s); - if (p->name) kputsn(p->name, strlen(p->name), s); - if (p->d >= 0) { - sprintf(numbuf, ":%g", p->d); - kputsn(numbuf, strlen(numbuf), s); - } - } else kputsn(p->name, strlen(p->name), s); -} - -void kn_format(const knhx1_t *node, int root, kstring_t *s) // TODO: get rid of recursion -{ - char numbuf[128]; - format_node_recur(node, &node[root], s, numbuf); -} - -#ifdef KNHX_MAIN -int main(int argc, char *argv[]) -{ - char *s = "((a[abc],d1)x:0.5,((b[&&NHX:S=MOUSE],h2)[&&NHX:S=HUMAN:B=99][blabla][&&NHX:K=foo],c))"; - knhx1_t *node; - int i, j, n, error; - kstring_t str; - node = kn_parse(s, &n, &error); - for (i = 0; i < n; ++i) { - knhx1_t *p = node + i; - printf("[%d] %s\t%d\t%d\t%g", i, p->name, p->parent, p->n, p->d); - for (j = 0; j < p->n; ++j) - printf("\t%d", p->child[j]); - putchar('\n'); - } - str.l = str.m = 0; str.s = 0; - kn_format(node, n-1, &str); - puts(str.s); - free(str.s); - return 0; -} -#endif diff --git a/web/server/h2o/libh2o/deps/klib/knhx.h b/web/server/h2o/libh2o/deps/klib/knhx.h deleted file mode 100644 index dbad7dd94..000000000 --- a/web/server/h2o/libh2o/deps/klib/knhx.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef KNHX_H_ -#define KNHX_H_ - -#define KNERR_MISSING_LEFT 0x01 -#define KNERR_MISSING_RGHT 0x02 -#define KNERR_BRACKET 0x04 -#define KNERR_COLON 0x08 - -typedef struct { - int parent, n; - int *child; - char *name; - double d; -} knhx1_t; - -#ifndef KSTRING_T -#define KSTRING_T kstring_t -typedef struct __kstring_t { - size_t l, m; - char *s; -} kstring_t; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - - knhx1_t *kn_parse(const char *nhx, int *_n, int *_error); - void kn_format(const knhx1_t *node, int root, kstring_t *s); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/web/server/h2o/libh2o/deps/klib/kopen.c b/web/server/h2o/libh2o/deps/klib/kopen.c deleted file mode 100644 index f72735c42..000000000 --- a/web/server/h2o/libh2o/deps/klib/kopen.c +++ /dev/null @@ -1,343 +0,0 @@ -#include <stdio.h> -#include <fcntl.h> -#include <errno.h> -#include <ctype.h> -#include <unistd.h> -#include <string.h> -#include <stdlib.h> -#include <signal.h> -#include <sys/types.h> -#ifndef _WIN32 -#include <netdb.h> -#include <arpa/inet.h> -#include <sys/socket.h> -#endif - -#ifdef _WIN32 -#define _KO_NO_NET -#endif - -#ifndef _KO_NO_NET -static int socket_wait(int fd, int is_read) -{ - fd_set fds, *fdr = 0, *fdw = 0; - struct timeval tv; - int ret; - tv.tv_sec = 5; tv.tv_usec = 0; // 5 seconds time out - FD_ZERO(&fds); - FD_SET(fd, &fds); - if (is_read) fdr = &fds; - else fdw = &fds; - ret = select(fd+1, fdr, fdw, 0, &tv); - if (ret == -1) perror("select"); - return ret; -} - -static int socket_connect(const char *host, const char *port) -{ -#define __err_connect(func) do { perror(func); freeaddrinfo(res); return -1; } while (0) - - int on = 1, fd; - struct linger lng = { 0, 0 }; - struct addrinfo hints, *res = 0; - memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - if (getaddrinfo(host, port, &hints, &res) != 0) __err_connect("getaddrinfo"); - if ((fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1) __err_connect("socket"); - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) __err_connect("setsockopt"); - if (setsockopt(fd, SOL_SOCKET, SO_LINGER, &lng, sizeof(lng)) == -1) __err_connect("setsockopt"); - if (connect(fd, res->ai_addr, res->ai_addrlen) != 0) __err_connect("connect"); - freeaddrinfo(res); - return fd; -#undef __err_connect -} - -static int http_open(const char *fn) -{ - char *p, *proxy, *q, *http_host, *host, *port, *path, *buf; - int fd, ret, l; - - /* parse URL; adapted from khttp_parse_url() in knetfile.c */ - if (strstr(fn, "http://") != fn) return 0; - // set ->http_host - for (p = (char*)fn + 7; *p && *p != '/'; ++p); - l = p - fn - 7; - http_host = calloc(l + 1, 1); - strncpy(http_host, fn + 7, l); - http_host[l] = 0; - for (q = http_host; *q && *q != ':'; ++q); - if (*q == ':') *q++ = 0; - // get http_proxy - proxy = getenv("http_proxy"); - // set host, port and path - if (proxy == 0) { - host = strdup(http_host); // when there is no proxy, server name is identical to http_host name. - port = strdup(*q? q : "80"); - path = strdup(*p? p : "/"); - } else { - host = (strstr(proxy, "http://") == proxy)? strdup(proxy + 7) : strdup(proxy); - for (q = host; *q && *q != ':'; ++q); - if (*q == ':') *q++ = 0; - port = strdup(*q? q : "80"); - path = strdup(fn); - } - - /* connect; adapted from khttp_connect() in knetfile.c */ - l = 0; - fd = socket_connect(host, port); - buf = calloc(0x10000, 1); // FIXME: I am lazy... But in principle, 64KB should be large enough. - l += sprintf(buf + l, "GET %s HTTP/1.0\r\nHost: %s\r\n", path, http_host); - l += sprintf(buf + l, "\r\n"); - write(fd, buf, l); - l = 0; - while (read(fd, buf + l, 1)) { // read HTTP header; FIXME: bad efficiency - if (buf[l] == '\n' && l >= 3) - if (strncmp(buf + l - 3, "\r\n\r\n", 4) == 0) break; - ++l; - } - buf[l] = 0; - if (l < 14) { // prematured header - close(fd); - fd = -1; - } - ret = strtol(buf + 8, &p, 0); // HTTP return code - if (ret != 200) { - close(fd); - fd = -1; - } - free(buf); free(http_host); free(host); free(port); free(path); - return fd; -} - -typedef struct { - int max_response, ctrl_fd; - char *response; -} ftpaux_t; - -static int kftp_get_response(ftpaux_t *aux) -{ - unsigned char c; - int n = 0; - char *p; - if (socket_wait(aux->ctrl_fd, 1) <= 0) return 0; - while (read(aux->ctrl_fd, &c, 1)) { // FIXME: this is *VERY BAD* for unbuffered I/O - if (n >= aux->max_response) { - aux->max_response = aux->max_response? aux->max_response<<1 : 256; - aux->response = realloc(aux->response, aux->max_response); - } - aux->response[n++] = c; - if (c == '\n') { - if (n >= 4 && isdigit(aux->response[0]) && isdigit(aux->response[1]) && isdigit(aux->response[2]) - && aux->response[3] != '-') break; - n = 0; - continue; - } - } - if (n < 2) return -1; - aux->response[n-2] = 0; - return strtol(aux->response, &p, 0); -} - -static int kftp_send_cmd(ftpaux_t *aux, const char *cmd, int is_get) -{ - if (socket_wait(aux->ctrl_fd, 0) <= 0) return -1; // socket is not ready for writing - write(aux->ctrl_fd, cmd, strlen(cmd)); - return is_get? kftp_get_response(aux) : 0; -} - -static int ftp_open(const char *fn) -{ - char *p, *host = 0, *port = 0, *retr = 0; - char host2[80], port2[10]; - int v[6], l, fd = -1, ret, pasv_port, pasv_ip[4]; - ftpaux_t aux; - - /* parse URL */ - if (strstr(fn, "ftp://") != fn) return 0; - for (p = (char*)fn + 6; *p && *p != '/'; ++p); - if (*p != '/') return 0; - l = p - fn - 6; - port = strdup("21"); - host = calloc(l + 1, 1); - strncpy(host, fn + 6, l); - retr = calloc(strlen(p) + 8, 1); - sprintf(retr, "RETR %s\r\n", p); - - /* connect to ctrl */ - memset(&aux, 0, sizeof(ftpaux_t)); - aux.ctrl_fd = socket_connect(host, port); - if (aux.ctrl_fd == -1) goto ftp_open_end; /* fail to connect ctrl */ - - /* connect to the data stream */ - kftp_get_response(&aux); - kftp_send_cmd(&aux, "USER anonymous\r\n", 1); - kftp_send_cmd(&aux, "PASS kopen@\r\n", 1); - kftp_send_cmd(&aux, "TYPE I\r\n", 1); - kftp_send_cmd(&aux, "PASV\r\n", 1); - for (p = aux.response; *p && *p != '('; ++p); - if (*p != '(') goto ftp_open_end; - ++p; - sscanf(p, "%d,%d,%d,%d,%d,%d", &v[0], &v[1], &v[2], &v[3], &v[4], &v[5]); - memcpy(pasv_ip, v, 4 * sizeof(int)); - pasv_port = (v[4]<<8&0xff00) + v[5]; - kftp_send_cmd(&aux, retr, 0); - sprintf(host2, "%d.%d.%d.%d", pasv_ip[0], pasv_ip[1], pasv_ip[2], pasv_ip[3]); - sprintf(port2, "%d", pasv_port); - fd = socket_connect(host2, port2); - if (fd == -1) goto ftp_open_end; - ret = kftp_get_response(&aux); - if (ret != 150) { - close(fd); - fd = -1; - } - close(aux.ctrl_fd); - -ftp_open_end: - free(host); free(port); free(retr); free(aux.response); - return fd; -} -#endif /* !defined(_KO_NO_NET) */ - -static char **cmd2argv(const char *cmd) -{ - int i, beg, end, argc; - char **argv, *p, *q, *str; - end = strlen(cmd); - for (i = end - 1; i >= 0; --i) - if (!isspace(cmd[i])) break; - end = i + 1; - for (beg = 0; beg < end; ++beg) - if (!isspace(cmd[beg])) break; - if (beg == end) return 0; - for (i = beg + 1, argc = 0; i < end; ++i) - if (isspace(cmd[i]) && !isspace(cmd[i-1])) - ++argc; - argv = (char**)calloc(argc + 2, sizeof(void*)); - argv[0] = str = (char*)calloc(end - beg + 1, 1); - strncpy(argv[0], cmd + beg, end - beg); - for (i = argc = 1, q = p = str; i < end - beg; ++i) - if (isspace(str[i])) str[i] = 0; - else if (str[i] && str[i-1] == 0) argv[argc++] = &str[i]; - return argv; -} - -#define KO_STDIN 1 -#define KO_FILE 2 -#define KO_PIPE 3 -#define KO_HTTP 4 -#define KO_FTP 5 - -typedef struct { - int type, fd; - pid_t pid; -} koaux_t; - -void *kopen(const char *fn, int *_fd) -{ - koaux_t *aux = 0; - *_fd = -1; - if (strstr(fn, "http://") == fn) { - aux = calloc(1, sizeof(koaux_t)); - aux->type = KO_HTTP; - aux->fd = http_open(fn); - } else if (strstr(fn, "ftp://") == fn) { - aux = calloc(1, sizeof(koaux_t)); - aux->type = KO_FTP; - aux->fd = ftp_open(fn); - } else if (strcmp(fn, "-") == 0) { - aux = calloc(1, sizeof(koaux_t)); - aux->type = KO_STDIN; - aux->fd = STDIN_FILENO; - } else { - const char *p, *q; - for (p = fn; *p; ++p) - if (!isspace(*p)) break; - if (*p == '<') { // pipe open - int need_shell, pfd[2]; - pid_t pid; - // a simple check to see if we need to invoke a shell; not always working - for (q = p + 1; *q; ++q) - if (ispunct(*q) && *q != '.' && *q != '_' && *q != '-' && *q != ':') - break; - need_shell = (*q != 0); - pipe(pfd); - pid = vfork(); - if (pid == -1) { /* vfork() error */ - close(pfd[0]); close(pfd[1]); - return 0; - } - if (pid == 0) { /* the child process */ - char **argv; /* FIXME: I do not know if this will lead to a memory leak */ - close(pfd[0]); - dup2(pfd[1], STDOUT_FILENO); - close(pfd[1]); - if (!need_shell) { - argv = cmd2argv(p + 1); - execvp(argv[0], argv); - free(argv[0]); free(argv); - } else execl("/bin/sh", "sh", "-c", p + 1, NULL); - exit(1); - } else { /* parent process */ - close(pfd[1]); - aux = calloc(1, sizeof(koaux_t)); - aux->type = KO_PIPE; - aux->fd = pfd[0]; - aux->pid = pid; - } - } else { -#ifdef _WIN32 - *_fd = open(fn, O_RDONLY | O_BINARY); -#else - *_fd = open(fn, O_RDONLY); -#endif - if (*_fd) { - aux = calloc(1, sizeof(koaux_t)); - aux->type = KO_FILE; - aux->fd = *_fd; - } - } - } - *_fd = aux->fd; - return aux; -} - -int kclose(void *a) -{ - koaux_t *aux = (koaux_t*)a; - if (aux->type == KO_PIPE) { - int status; - pid_t pid; - pid = waitpid(aux->pid, &status, WNOHANG); - if (pid != aux->pid) kill(aux->pid, 15); - } - return 0; -} - -#ifdef _KO_MAIN -#define BUF_SIZE 0x10000 -int main(int argc, char *argv[]) -{ - void *x; - int l, fd; - unsigned char buf[BUF_SIZE]; - FILE *fp; - if (argc == 1) { - fprintf(stderr, "Usage: kopen <file>\n"); - return 1; - } - x = kopen(argv[1], &fd); - fp = fdopen(fd, "r"); - if (fp == 0) { - fprintf(stderr, "ERROR: fail to open the input\n"); - return 1; - } - do { - if ((l = fread(buf, 1, BUF_SIZE, fp)) != 0) - fwrite(buf, 1, l, stdout); - } while (l == BUF_SIZE); - fclose(fp); - kclose(x); - return 0; -} -#endif diff --git a/web/server/h2o/libh2o/deps/klib/ksa.c b/web/server/h2o/libh2o/deps/klib/ksa.c deleted file mode 100644 index 18f686d11..000000000 --- a/web/server/h2o/libh2o/deps/klib/ksa.c +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Copyright (c) 2008 Yuta Mori All Rights Reserved. - * 2011 Attractive Chaos <attractor@live.co.uk> - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -/* This is a library for constructing the suffix array for a string containing - * multiple sentinels with sentinels all represented by 0. The last symbol in - * the string must be a sentinel. The library is modified from an early version - * of Yuta Mori's SAIS library, but is slower than the lastest SAIS by about - * 30%, partly due to the recent optimization Yuta has applied and partly due - * to the extra comparisons between sentinels. This is not the first effort in - * supporting multi-sentinel strings, but is probably the easiest to use. */ - -#include <stdlib.h> - -#ifdef _KSA64 -#include <stdint.h> -typedef int64_t saint_t; -#define SAINT_MAX INT64_MAX -#define SAIS_CORE ksa_core64 -#define SAIS_BWT ksa_bwt64 -#define SAIS_MAIN ksa_sa64 -#else -#include <limits.h> -typedef int saint_t; -#define SAINT_MAX INT_MAX -#define SAIS_CORE ksa_core -#define SAIS_BWT ksa_bwt -#define SAIS_MAIN ksa_sa -#endif - -/* T is of type "const unsigned char*". If T[i] is a sentinel, chr(i) takes a negative value */ -#define chr(i) (cs == sizeof(saint_t) ? ((const saint_t *)T)[i] : (T[i]? (saint_t)T[i] : i - SAINT_MAX)) - -/** Count the occurrences of each symbol */ -static void getCounts(const unsigned char *T, saint_t *C, saint_t n, saint_t k, int cs) -{ - saint_t i; - for (i = 0; i < k; ++i) C[i] = 0; - for (i = 0; i < n; ++i) { - saint_t c = chr(i); - ++C[c > 0? c : 0]; - } -} - -/** - * Find the end of each bucket - * - * @param C occurrences computed by getCounts(); input - * @param B start/end of each bucket; output - * @param k size of alphabet - * @param end compute the end of bucket if true; otherwise compute the end - */ -static inline void getBuckets(const saint_t *C, saint_t *B, saint_t k, saint_t end) -{ - saint_t i, sum = 0; - if (end) for (i = 0; i < k; ++i) sum += C[i], B[i] = sum; - else for (i = 0; i < k; ++i) sum += C[i], B[i] = sum - C[i]; -} - -/** Induced sort */ -static void induceSA(const unsigned char *T, saint_t *SA, saint_t *C, saint_t *B, saint_t n, saint_t k, saint_t cs) -{ - saint_t *b, i, j; - saint_t c0, c1; - /* left-to-right induced sort (for L-type) */ - if (C == B) getCounts(T, C, n, k, cs); - getBuckets(C, B, k, 0); /* find starts of buckets */ - for (i = 0, b = 0, c1 = -1; i < n; ++i) { - j = SA[i], SA[i] = ~j; - if (0 < j) { /* >0 if j-1 is L-type; <0 if S-type; ==0 undefined */ - --j; - if ((c0 = chr(j)) != c1) { - B[c1 > 0? c1 : 0] = b - SA; - c1 = c0; - b = SA + B[c1 > 0? c1 : 0]; - } - *b++ = (0 < j && chr(j - 1) < c1) ? ~j : j; - } - } - /* right-to-left induced sort (for S-type) */ - if (C == B) getCounts(T, C, n, k, cs); - getBuckets(C, B, k, 1); /* find ends of buckets */ - for (i = n - 1, b = 0, c1 = -1; 0 <= i; --i) { - if (0 < (j = SA[i])) { /* the prefix is S-type */ - --j; - if ((c0 = chr(j)) != c1) { - B[c1 > 0? c1 : 0] = b - SA; - c1 = c0; - b = SA + B[c1 > 0? c1 : 0]; - } - if (c0 > 0) *--b = (j == 0 || chr(j - 1) > c1) ? ~j : j; - } else SA[i] = ~j; /* if L-type, change the sign */ - } -} - -/** - * Recursively construct the suffix array for a string containing multiple - * sentinels. NULL is taken as the sentinel. - * - * @param T NULL terminated input string (there can be multiple NULLs) - * @param SA output suffix array - * @param fs working space available in SA (typically 0 when first called) - * @param n length of T, including the trailing NULL - * @param k size of the alphabet (typically 256 when first called) - * @param cs # bytes per element in T; 1 or sizeof(saint_t) (typically 1 when first called) - * - * @return 0 upon success - */ -int SAIS_CORE(const unsigned char *T, saint_t *SA, saint_t fs, saint_t n, saint_t k, int cs) -{ - saint_t *C, *B; - saint_t i, j, c, m, q, qlen, name; - saint_t c0, c1; - - /* STAGE I: reduce the problem by at least 1/2 sort all the S-substrings */ - if (k <= fs) C = SA + n, B = (k <= fs - k) ? C + k : C; - else { - if ((C = (saint_t*)malloc(k * (1 + (cs == 1)) * sizeof(saint_t))) == NULL) return -2; - B = cs == 1? C + k : C; - } - getCounts(T, C, n, k, cs); - getBuckets(C, B, k, 1); /* find ends of buckets */ - for (i = 0; i < n; ++i) SA[i] = 0; - /* mark L and S (the t array in Nong et al.), and keep the positions of LMS in the buckets */ - for (i = n - 2, c = 1, c1 = chr(n - 1); 0 <= i; --i, c1 = c0) { - if ((c0 = chr(i)) < c1 + c) c = 1; /* c1 = chr(i+1); c==1 if in an S run */ - else if (c) SA[--B[c1 > 0? c1 : 0]] = i + 1, c = 0; - } - induceSA(T, SA, C, B, n, k, cs); - if (fs < k) free(C); - /* pack all the sorted LMS into the first m items of SA - 2*m must be not larger than n (see Nong et al. for the proof) */ - for (i = 0, m = 0; i < n; ++i) { - saint_t p = SA[i]; - if (p == n - 1) SA[m++] = p; - else if (0 < p && chr(p - 1) > (c0 = chr(p))) { - for (j = p + 1; j < n && c0 == (c1 = chr(j)); ++j); - if (j < n && c0 < c1) SA[m++] = p; - } - } - for (i = m; i < n; ++i) SA[i] = 0; /* init the name array buffer */ - /* store the length of all substrings */ - for (i = n - 2, j = n, c = 1, c1 = chr(n - 1); 0 <= i; --i, c1 = c0) { - if ((c0 = chr(i)) < c1 + c) c = 1; /* c1 = chr(i+1) */ - else if (c) SA[m + ((i + 1) >> 1)] = j - i - 1, j = i + 1, c = 0; - } - /* find the lexicographic names of all substrings */ - for (i = 0, name = 0, q = n, qlen = 0; i < m; ++i) { - saint_t p = SA[i], plen = SA[m + (p >> 1)], diff = 1; - if (plen == qlen) { - for (j = 0; j < plen && chr(p + j) == chr(q + j); j++); - if (j == plen) diff = 0; - } - if (diff) ++name, q = p, qlen = plen; - SA[m + (p >> 1)] = name; - } - - /* STAGE II: solve the reduced problem; recurse if names are not yet unique */ - if (name < m) { - saint_t *RA = SA + n + fs - m - 1; - for (i = n - 1, j = m - 1; m <= i; --i) - if (SA[i] != 0) RA[j--] = SA[i]; - RA[m] = 0; // add a sentinel; in the resulting SA, SA[0]==m always stands - if (SAIS_CORE((unsigned char *)RA, SA, fs + n - m * 2 - 2, m + 1, name + 1, sizeof(saint_t)) != 0) return -2; - for (i = n - 2, j = m - 1, c = 1, c1 = chr(n - 1); 0 <= i; --i, c1 = c0) { - if ((c0 = chr(i)) < c1 + c) c = 1; - else if (c) RA[j--] = i + 1, c = 0; /* get p1 */ - } - for (i = 0; i < m; ++i) SA[i] = RA[SA[i+1]]; /* get index */ - } - - /* STAGE III: induce the result for the original problem */ - if (k <= fs) C = SA + n, B = (k <= fs - k) ? C + k : C; - else { - if ((C = (saint_t*)malloc(k * (1 + (cs == 1)) * sizeof(saint_t))) == NULL) return -2; - B = cs == 1? C + k : C; - } - /* put all LMS characters into their buckets */ - getCounts(T, C, n, k, cs); - getBuckets(C, B, k, 1); /* find ends of buckets */ - for (i = m; i < n; ++i) SA[i] = 0; /* init SA[m..n-1] */ - for (i = m - 1; 0 <= i; --i) { - j = SA[i], SA[i] = 0; - c = chr(j); - SA[--B[c > 0? c : 0]] = j; - } - induceSA(T, SA, C, B, n, k, cs); - if (fs < k) free(C); - return 0; -} - -/** - * Construct the suffix array for a NULL terminated string possibly containing - * multiple sentinels (NULLs). - * - * @param T[0..n-1] NULL terminated input string - * @param SA[0..n-1] output suffix array - * @param n length of the given string, including NULL - * @param k size of the alphabet including the sentinel; no more than 256 - * @return 0 upon success - */ -int SAIS_MAIN(const unsigned char *T, saint_t *SA, saint_t n, int k) -{ - if (T == NULL || SA == NULL || T[n - 1] != '\0' || n <= 0) return -1; - if (k < 0 || k > 256) k = 256; - return SAIS_CORE(T, SA, 0, n, (saint_t)k, 1); -} - -int SAIS_BWT(unsigned char *T, saint_t n, int k) -{ - saint_t *SA, i; - int ret; - if ((SA = malloc(n * sizeof(saint_t))) == 0) return -1; - if ((ret = SAIS_MAIN(T, SA, n, k)) != 0) return ret; - for (i = 0; i < n; ++i) - if (SA[i]) SA[i] = T[SA[i] - 1]; // if SA[i]==0, SA[i]=0 - for (i = 0; i < n; ++i) T[i] = SA[i]; - free(SA); - return 0; -} diff --git a/web/server/h2o/libh2o/deps/klib/kseq.h b/web/server/h2o/libh2o/deps/klib/kseq.h deleted file mode 100644 index b2238d1d3..000000000 --- a/web/server/h2o/libh2o/deps/klib/kseq.h +++ /dev/null @@ -1,235 +0,0 @@ -/* The MIT License - - Copyright (c) 2008, 2009, 2011 Attractive Chaos <attractor@live.co.uk> - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. -*/ - -/* Last Modified: 05MAR2012 */ - -#ifndef AC_KSEQ_H -#define AC_KSEQ_H - -#include <ctype.h> -#include <string.h> -#include <stdlib.h> - -#define KS_SEP_SPACE 0 // isspace(): \t, \n, \v, \f, \r -#define KS_SEP_TAB 1 // isspace() && !' ' -#define KS_SEP_LINE 2 // line separator: "\n" (Unix) or "\r\n" (Windows) -#define KS_SEP_MAX 2 - -#define __KS_TYPE(type_t) \ - typedef struct __kstream_t { \ - unsigned char *buf; \ - int begin, end, is_eof; \ - type_t f; \ - } kstream_t; - -#define ks_eof(ks) ((ks)->is_eof && (ks)->begin >= (ks)->end) -#define ks_rewind(ks) ((ks)->is_eof = (ks)->begin = (ks)->end = 0) - -#define __KS_BASIC(type_t, __bufsize) \ - static inline kstream_t *ks_init(type_t f) \ - { \ - kstream_t *ks = (kstream_t*)calloc(1, sizeof(kstream_t)); \ - ks->f = f; \ - ks->buf = (unsigned char*)malloc(__bufsize); \ - return ks; \ - } \ - static inline void ks_destroy(kstream_t *ks) \ - { \ - if (ks) { \ - free(ks->buf); \ - free(ks); \ - } \ - } - -#define __KS_GETC(__read, __bufsize) \ - static inline int ks_getc(kstream_t *ks) \ - { \ - if (ks->is_eof && ks->begin >= ks->end) return -1; \ - if (ks->begin >= ks->end) { \ - ks->begin = 0; \ - ks->end = __read(ks->f, ks->buf, __bufsize); \ - if (ks->end == 0) { ks->is_eof = 1; return -1;} \ - } \ - return (int)ks->buf[ks->begin++]; \ - } - -#ifndef KSTRING_T -#define KSTRING_T kstring_t -typedef struct __kstring_t { - size_t l, m; - char *s; -} kstring_t; -#endif - -#ifndef kroundup32 -#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) -#endif - -#define __KS_GETUNTIL(__read, __bufsize) \ - static int ks_getuntil2(kstream_t *ks, int delimiter, kstring_t *str, int *dret, int append) \ - { \ - int gotany = 0; \ - if (dret) *dret = 0; \ - str->l = append? str->l : 0; \ - for (;;) { \ - int i; \ - if (ks->begin >= ks->end) { \ - if (!ks->is_eof) { \ - ks->begin = 0; \ - ks->end = __read(ks->f, ks->buf, __bufsize); \ - if (ks->end == 0) { ks->is_eof = 1; break; } \ - } else break; \ - } \ - if (delimiter == KS_SEP_LINE) { \ - for (i = ks->begin; i < ks->end; ++i) \ - if (ks->buf[i] == '\n') break; \ - } else if (delimiter > KS_SEP_MAX) { \ - for (i = ks->begin; i < ks->end; ++i) \ - if (ks->buf[i] == delimiter) break; \ - } else if (delimiter == KS_SEP_SPACE) { \ - for (i = ks->begin; i < ks->end; ++i) \ - if (isspace(ks->buf[i])) break; \ - } else if (delimiter == KS_SEP_TAB) { \ - for (i = ks->begin; i < ks->end; ++i) \ - if (isspace(ks->buf[i]) && ks->buf[i] != ' ') break; \ - } else i = 0; /* never come to here! */ \ - if (str->m - str->l < (size_t)(i - ks->begin + 1)) { \ - str->m = str->l + (i - ks->begin) + 1; \ - kroundup32(str->m); \ - str->s = (char*)realloc(str->s, str->m); \ - } \ - gotany = 1; \ - memcpy(str->s + str->l, ks->buf + ks->begin, i - ks->begin); \ - str->l = str->l + (i - ks->begin); \ - ks->begin = i + 1; \ - if (i < ks->end) { \ - if (dret) *dret = ks->buf[i]; \ - break; \ - } \ - } \ - if (!gotany && ks_eof(ks)) return -1; \ - if (str->s == 0) { \ - str->m = 1; \ - str->s = (char*)calloc(1, 1); \ - } else if (delimiter == KS_SEP_LINE && str->l > 1 && str->s[str->l-1] == '\r') --str->l; \ - str->s[str->l] = '\0'; \ - return str->l; \ - } \ - static inline int ks_getuntil(kstream_t *ks, int delimiter, kstring_t *str, int *dret) \ - { return ks_getuntil2(ks, delimiter, str, dret, 0); } - -#define KSTREAM_INIT(type_t, __read, __bufsize) \ - __KS_TYPE(type_t) \ - __KS_BASIC(type_t, __bufsize) \ - __KS_GETC(__read, __bufsize) \ - __KS_GETUNTIL(__read, __bufsize) - -#define kseq_rewind(ks) ((ks)->last_char = (ks)->f->is_eof = (ks)->f->begin = (ks)->f->end = 0) - -#define __KSEQ_BASIC(SCOPE, type_t) \ - SCOPE kseq_t *kseq_init(type_t fd) \ - { \ - kseq_t *s = (kseq_t*)calloc(1, sizeof(kseq_t)); \ - s->f = ks_init(fd); \ - return s; \ - } \ - SCOPE void kseq_destroy(kseq_t *ks) \ - { \ - if (!ks) return; \ - free(ks->name.s); free(ks->comment.s); free(ks->seq.s); free(ks->qual.s); \ - ks_destroy(ks->f); \ - free(ks); \ - } - -/* Return value: - >=0 length of the sequence (normal) - -1 end-of-file - -2 truncated quality string - */ -#define __KSEQ_READ(SCOPE) \ - SCOPE int kseq_read(kseq_t *seq) \ - { \ - int c; \ - kstream_t *ks = seq->f; \ - if (seq->last_char == 0) { /* then jump to the next header line */ \ - while ((c = ks_getc(ks)) != -1 && c != '>' && c != '@'); \ - if (c == -1) return -1; /* end of file */ \ - seq->last_char = c; \ - } /* else: the first header char has been read in the previous call */ \ - seq->comment.l = seq->seq.l = seq->qual.l = 0; /* reset all members */ \ - if (ks_getuntil(ks, 0, &seq->name, &c) < 0) return -1; /* normal exit: EOF */ \ - if (c != '\n') ks_getuntil(ks, KS_SEP_LINE, &seq->comment, 0); /* read FASTA/Q comment */ \ - if (seq->seq.s == 0) { /* we can do this in the loop below, but that is slower */ \ - seq->seq.m = 256; \ - seq->seq.s = (char*)malloc(seq->seq.m); \ - } \ - while ((c = ks_getc(ks)) != -1 && c != '>' && c != '+' && c != '@') { \ - if (c == '\n') continue; /* skip empty lines */ \ - seq->seq.s[seq->seq.l++] = c; /* this is safe: we always have enough space for 1 char */ \ - ks_getuntil2(ks, KS_SEP_LINE, &seq->seq, 0, 1); /* read the rest of the line */ \ - } \ - if (c == '>' || c == '@') seq->last_char = c; /* the first header char has been read */ \ - if (seq->seq.l + 1 >= seq->seq.m) { /* seq->seq.s[seq->seq.l] below may be out of boundary */ \ - seq->seq.m = seq->seq.l + 2; \ - kroundup32(seq->seq.m); /* rounded to the next closest 2^k */ \ - seq->seq.s = (char*)realloc(seq->seq.s, seq->seq.m); \ - } \ - seq->seq.s[seq->seq.l] = 0; /* null terminated string */ \ - if (c != '+') return seq->seq.l; /* FASTA */ \ - if (seq->qual.m < seq->seq.m) { /* allocate memory for qual in case insufficient */ \ - seq->qual.m = seq->seq.m; \ - seq->qual.s = (char*)realloc(seq->qual.s, seq->qual.m); \ - } \ - while ((c = ks_getc(ks)) != -1 && c != '\n'); /* skip the rest of '+' line */ \ - if (c == -1) return -2; /* error: no quality string */ \ - while (ks_getuntil2(ks, KS_SEP_LINE, &seq->qual, 0, 1) >= 0 && seq->qual.l < seq->seq.l); \ - seq->last_char = 0; /* we have not come to the next header line */ \ - if (seq->seq.l != seq->qual.l) return -2; /* error: qual string is of a different length */ \ - return seq->seq.l; \ - } - -#define __KSEQ_TYPE(type_t) \ - typedef struct { \ - kstring_t name, comment, seq, qual; \ - int last_char; \ - kstream_t *f; \ - } kseq_t; - -#define KSEQ_INIT2(SCOPE, type_t, __read) \ - KSTREAM_INIT(type_t, __read, 16384) \ - __KSEQ_TYPE(type_t) \ - __KSEQ_BASIC(SCOPE, type_t) \ - __KSEQ_READ(SCOPE) - -#define KSEQ_INIT(type_t, __read) KSEQ_INIT2(static, type_t, __read) - -#define KSEQ_DECLARE(type_t) \ - __KS_TYPE(type_t) \ - __KSEQ_TYPE(type_t) \ - extern kseq_t *kseq_init(type_t fd); \ - void kseq_destroy(kseq_t *ks); \ - int kseq_read(kseq_t *seq); - -#endif diff --git a/web/server/h2o/libh2o/deps/klib/kson.c b/web/server/h2o/libh2o/deps/klib/kson.c deleted file mode 100644 index a8bf1601f..000000000 --- a/web/server/h2o/libh2o/deps/klib/kson.c +++ /dev/null @@ -1,253 +0,0 @@ -#include <string.h> -#include <stdlib.h> -#include <stdarg.h> -#include <assert.h> -#include <ctype.h> -#include <stdio.h> -#include "kson.h" - -/************* - *** Parse *** - *************/ - -kson_node_t *kson_parse_core(const char *json, long *_n, int *error, long *parsed_len) -{ - long *stack = 0, top = 0, max = 0, n_a = 0, m_a = 0, i, j; - kson_node_t *a = 0, *u; - const char *p, *q; - size_t *tmp; - -#define __push_back(y) do { \ - if (top == max) { \ - max = max? max<<1 : 4; \ - stack = (long*)realloc(stack, sizeof(long) * max); \ - } \ - stack[top++] = (y); \ - } while (0) - -#define __new_node(z) do { \ - if (n_a == m_a) { \ - long old_m = m_a; \ - m_a = m_a? m_a<<1 : 4; \ - a = (kson_node_t*)realloc(a, sizeof(kson_node_t) * m_a); \ - memset(a + old_m, 0, sizeof(kson_node_t) * (m_a - old_m)); \ - } \ - *(z) = &a[n_a++]; \ - } while (0) - - assert(sizeof(size_t) == sizeof(kson_node_t*)); - *error = KSON_OK; - for (p = json; *p; ++p) { - while (*p && isspace(*p)) ++p; - if (*p == 0) break; - if (*p == ',') { // comma is somewhat redundant - } else if (*p == '[' || *p == '{') { - int t = *p == '['? -1 : -2; - if (top < 2 || stack[top-1] != -3) { // unnamed internal node - __push_back(n_a); - __new_node(&u); - __push_back(t); - } else stack[top-1] = t; // named internal node - } else if (*p == ']' || *p == '}') { - long i, start, t = *p == ']'? -1 : -2; - for (i = top - 1; i >= 0 && stack[i] != t; --i); - if (i < 0) { // error: an extra right bracket - *error = KSON_ERR_EXTRA_RIGHT; - break; - } - start = i; - u = &a[stack[start-1]]; - u->key = u->v.str; - u->n = top - 1 - start; - u->v.child = (kson_node_t**)malloc(u->n * sizeof(kson_node_t*)); - tmp = (size_t*)u->v.child; - for (i = start + 1; i < top; ++i) - tmp[i - start - 1] = stack[i]; - u->type = *p == ']'? KSON_TYPE_BRACKET : KSON_TYPE_BRACE; - if ((top = start) == 1) break; // completed one object; remaining characters discarded - } else if (*p == ':') { - if (top == 0 || stack[top-1] == -3) { - *error = KSON_ERR_NO_KEY; - break; - } - __push_back(-3); - } else { - int c = *p; - // get the node to modify - if (top >= 2 && stack[top-1] == -3) { // we have a key:value pair here - --top; - u = &a[stack[top-1]]; - u->key = u->v.str; // move old value to key - } else { // don't know if this is a bare value or a key:value pair; keep it as a value for now - __push_back(n_a); - __new_node(&u); - } - // parse string - if (c == '\'' || c == '"') { - for (q = ++p; *q && *q != c; ++q) - if (*q == '\\') ++q; - } else { - for (q = p; *q && *q != ']' && *q != '}' && *q != ',' && *q != ':' && *q != '\n'; ++q) - if (*q == '\\') ++q; - } - u->v.str = (char*)malloc(q - p + 1); strncpy(u->v.str, p, q - p); u->v.str[q-p] = 0; // equivalent to u->v.str=strndup(p, q-p) - u->type = c == '\''? KSON_TYPE_SGL_QUOTE : c == '"'? KSON_TYPE_DBL_QUOTE : KSON_TYPE_NO_QUOTE; - p = c == '\'' || c == '"'? q : q - 1; - } - } - while (*p && isspace(*p)) ++p; // skip trailing blanks - if (parsed_len) *parsed_len = p - json; - if (top != 1) *error = KSON_ERR_EXTRA_LEFT; - - for (i = 0; i < n_a; ++i) - for (j = 0, u = &a[i], tmp = (size_t*)u->v.child; j < (long)u->n; ++j) - u->v.child[j] = &a[tmp[j]]; - - free(stack); - *_n = n_a; - return a; -} - -void kson_destroy(kson_t *kson) -{ - long i; - if (kson == 0) return; - for (i = 0; i < kson->n_nodes; ++i) { - free(kson->root[i].key); free(kson->root[i].v.str); - } - free(kson->root); free(kson); -} - -kson_t *kson_parse(const char *json) -{ - kson_t *kson; - int error; - kson = (kson_t*)calloc(1, sizeof(kson_t)); - kson->root = kson_parse_core(json, &kson->n_nodes, &error, 0); - if (error) { - kson_destroy(kson); - return 0; - } - return kson; -} - -/************* - *** Query *** - *************/ - -const kson_node_t *kson_by_path(const kson_node_t *p, int depth, ...) -{ - va_list ap; - va_start(ap, depth); - while (p && depth > 0) { - if (p->type == KSON_TYPE_BRACE) { - p = kson_by_key(p, va_arg(ap, const char*)); - } else if (p->type == KSON_TYPE_BRACKET) { - p = kson_by_index(p, va_arg(ap, long)); - } else break; - --depth; - } - va_end(ap); - return p; -} - -/************** - *** Fromat *** - **************/ - -void kson_format_recur(const kson_node_t *p, int depth) -{ - long i; - if (p->key) printf("\"%s\":", p->key); - if (p->type == KSON_TYPE_BRACKET || p->type == KSON_TYPE_BRACE) { - putchar(p->type == KSON_TYPE_BRACKET? '[' : '{'); - if (p->n) { - putchar('\n'); for (i = 0; i <= depth; ++i) fputs(" ", stdout); - for (i = 0; i < (long)p->n; ++i) { - if (i) { - int i; - putchar(','); - putchar('\n'); for (i = 0; i <= depth; ++i) fputs(" ", stdout); - } - kson_format_recur(p->v.child[i], depth + 1); - } - putchar('\n'); for (i = 0; i < depth; ++i) fputs(" ", stdout); - } - putchar(p->type == KSON_TYPE_BRACKET? ']' : '}'); - } else { - if (p->type != KSON_TYPE_NO_QUOTE) - putchar(p->type == KSON_TYPE_SGL_QUOTE? '\'' : '"'); - fputs(p->v.str, stdout); - if (p->type != KSON_TYPE_NO_QUOTE) - putchar(p->type == KSON_TYPE_SGL_QUOTE? '\'' : '"'); - } -} - -void kson_format(const kson_node_t *root) -{ - kson_format_recur(root, 0); - putchar('\n'); -} - -/********************* - *** Main function *** - *********************/ - -#ifdef KSON_MAIN -#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) -int main(int argc, char *argv[]) -{ - kson_t *kson = 0; - if (argc > 1) { - FILE *fp; - int len = 0, max = 0, tmp, i; - char *json = 0, buf[0x10000]; - if ((fp = fopen(argv[1], "rb")) != 0) { - // read the entire file into a string - while ((tmp = fread(buf, 1, 0x10000, fp)) != 0) { - if (len + tmp + 1 > max) { - max = len + tmp + 1; - kroundup32(max); - json = (char*)realloc(json, max); - } - memcpy(json + len, buf, tmp); - len += tmp; - } - fclose(fp); - // parse - kson = kson_parse(json); - free(json); - if (kson) { - kson_format(kson->root); - if (argc > 2) { - // path finding - const kson_node_t *p = kson->root; - for (i = 2; i < argc && p; ++i) { - if (p->type == KSON_TYPE_BRACKET) - p = kson_by_index(p, atoi(argv[i])); - else if (p->type == KSON_TYPE_BRACE) - p = kson_by_key(p, argv[i]); - else p = 0; - } - if (p) { - if (kson_is_internal(p)) printf("Reached an internal node\n"); - else printf("Value: %s\n", p->v.str); - } else printf("Failed to find the slot\n"); - } - } else printf("Failed to parse\n"); - } - } else { - kson = kson_parse("{'a' : 1,'b':[0,'isn\\'t',true],'d':[{\n\n\n}]}"); - if (kson) { - const kson_node_t *p = kson_by_path(kson->root, 2, "b", 1); - if (p) printf("*** %s\n", p->v.str); - else printf("!!! not found\n"); - kson_format(kson->root); - } else { - printf("Failed to parse\n"); - } - } - kson_destroy(kson); - return 0; -} -#endif diff --git a/web/server/h2o/libh2o/deps/klib/kson.h b/web/server/h2o/libh2o/deps/klib/kson.h deleted file mode 100644 index a03eb52f5..000000000 --- a/web/server/h2o/libh2o/deps/klib/kson.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef KSON_H -#define KSON_H - -#include <string.h> - -#define KSON_TYPE_NO_QUOTE 1 -#define KSON_TYPE_SGL_QUOTE 2 -#define KSON_TYPE_DBL_QUOTE 3 -#define KSON_TYPE_BRACKET 4 -#define KSON_TYPE_BRACE 5 - -#define KSON_OK 0 -#define KSON_ERR_EXTRA_LEFT 1 -#define KSON_ERR_EXTRA_RIGHT 2 -#define KSON_ERR_NO_KEY 3 - -typedef struct kson_node_s { - unsigned long long type:3, n:61; - char *key; - union { - struct kson_node_s **child; - char *str; - } v; -} kson_node_t; - -typedef struct { - long n_nodes; - kson_node_t *root; -} kson_t; - -#ifdef __cplusplus -extern "C" { -#endif - - kson_t *kson_parse(const char *json); - void kson_destroy(kson_t *kson); - const kson_node_t *kson_by_path(const kson_node_t *root, int path_len, ...); - void kson_format(const kson_node_t *root); - -#ifdef __cplusplus -} -#endif - -#define kson_is_internal(p) ((p)->type == KSON_TYPE_BRACKET || (p)->type == KSON_TYPE_BRACE) - -static inline const kson_node_t *kson_by_key(const kson_node_t *p, const char *key) -{ - long i; - if (!kson_is_internal(p)) return 0; - for (i = 0; i < (long)p->n; ++i) { - const kson_node_t *q = p->v.child[i]; - if (q->key && strcmp(q->key, key) == 0) - return q; - } - return 0; -} - -static inline const kson_node_t *kson_by_index(const kson_node_t *p, long i) -{ - if (!kson_is_internal(p)) return 0; - return 0 <= i && i < (long)p->n? p->v.child[i] : 0; -} - -#endif diff --git a/web/server/h2o/libh2o/deps/klib/ksort.h b/web/server/h2o/libh2o/deps/klib/ksort.h deleted file mode 100644 index 4da7a13ef..000000000 --- a/web/server/h2o/libh2o/deps/klib/ksort.h +++ /dev/null @@ -1,298 +0,0 @@ -/* The MIT License - - Copyright (c) 2008, 2011 Attractive Chaos <attractor@live.co.uk> - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. -*/ - -/* - 2011-04-10 (0.1.6): - - * Added sample - - 2011-03 (0.1.5): - - * Added shuffle/permutation - - 2008-11-16 (0.1.4): - - * Fixed a bug in introsort() that happens in rare cases. - - 2008-11-05 (0.1.3): - - * Fixed a bug in introsort() for complex comparisons. - - * Fixed a bug in mergesort(). The previous version is not stable. - - 2008-09-15 (0.1.2): - - * Accelerated introsort. On my Mac (not on another Linux machine), - my implementation is as fast as std::sort on random input. - - * Added combsort and in introsort, switch to combsort if the - recursion is too deep. - - 2008-09-13 (0.1.1): - - * Added k-small algorithm - - 2008-09-05 (0.1.0): - - * Initial version - -*/ - -#ifndef AC_KSORT_H -#define AC_KSORT_H - -#include <stdlib.h> -#include <string.h> - -typedef struct { - void *left, *right; - int depth; -} ks_isort_stack_t; - -#define KSORT_SWAP(type_t, a, b) { register type_t t=(a); (a)=(b); (b)=t; } - -#define KSORT_INIT(name, type_t, __sort_lt) \ - void ks_mergesort_##name(size_t n, type_t array[], type_t temp[]) \ - { \ - type_t *a2[2], *a, *b; \ - int curr, shift; \ - \ - a2[0] = array; \ - a2[1] = temp? temp : (type_t*)malloc(sizeof(type_t) * n); \ - for (curr = 0, shift = 0; (1ul<<shift) < n; ++shift) { \ - a = a2[curr]; b = a2[1-curr]; \ - if (shift == 0) { \ - type_t *p = b, *i, *eb = a + n; \ - for (i = a; i < eb; i += 2) { \ - if (i == eb - 1) *p++ = *i; \ - else { \ - if (__sort_lt(*(i+1), *i)) { \ - *p++ = *(i+1); *p++ = *i; \ - } else { \ - *p++ = *i; *p++ = *(i+1); \ - } \ - } \ - } \ - } else { \ - size_t i, step = 1ul<<shift; \ - for (i = 0; i < n; i += step<<1) { \ - type_t *p, *j, *k, *ea, *eb; \ - if (n < i + step) { \ - ea = a + n; eb = a; \ - } else { \ - ea = a + i + step; \ - eb = a + (n < i + (step<<1)? n : i + (step<<1)); \ - } \ - j = a + i; k = a + i + step; p = b + i; \ - while (j < ea && k < eb) { \ - if (__sort_lt(*k, *j)) *p++ = *k++; \ - else *p++ = *j++; \ - } \ - while (j < ea) *p++ = *j++; \ - while (k < eb) *p++ = *k++; \ - } \ - } \ - curr = 1 - curr; \ - } \ - if (curr == 1) { \ - type_t *p = a2[0], *i = a2[1], *eb = array + n; \ - for (; p < eb; ++i) *p++ = *i; \ - } \ - if (temp == 0) free(a2[1]); \ - } \ - void ks_heapadjust_##name(size_t i, size_t n, type_t l[]) \ - { \ - size_t k = i; \ - type_t tmp = l[i]; \ - while ((k = (k << 1) + 1) < n) { \ - if (k != n - 1 && __sort_lt(l[k], l[k+1])) ++k; \ - if (__sort_lt(l[k], tmp)) break; \ - l[i] = l[k]; i = k; \ - } \ - l[i] = tmp; \ - } \ - void ks_heapmake_##name(size_t lsize, type_t l[]) \ - { \ - size_t i; \ - for (i = (lsize >> 1) - 1; i != (size_t)(-1); --i) \ - ks_heapadjust_##name(i, lsize, l); \ - } \ - void ks_heapsort_##name(size_t lsize, type_t l[]) \ - { \ - size_t i; \ - for (i = lsize - 1; i > 0; --i) { \ - type_t tmp; \ - tmp = *l; *l = l[i]; l[i] = tmp; ks_heapadjust_##name(0, i, l); \ - } \ - } \ - static inline void __ks_insertsort_##name(type_t *s, type_t *t) \ - { \ - type_t *i, *j, swap_tmp; \ - for (i = s + 1; i < t; ++i) \ - for (j = i; j > s && __sort_lt(*j, *(j-1)); --j) { \ - swap_tmp = *j; *j = *(j-1); *(j-1) = swap_tmp; \ - } \ - } \ - void ks_combsort_##name(size_t n, type_t a[]) \ - { \ - const double shrink_factor = 1.2473309501039786540366528676643; \ - int do_swap; \ - size_t gap = n; \ - type_t tmp, *i, *j; \ - do { \ - if (gap > 2) { \ - gap = (size_t)(gap / shrink_factor); \ - if (gap == 9 || gap == 10) gap = 11; \ - } \ - do_swap = 0; \ - for (i = a; i < a + n - gap; ++i) { \ - j = i + gap; \ - if (__sort_lt(*j, *i)) { \ - tmp = *i; *i = *j; *j = tmp; \ - do_swap = 1; \ - } \ - } \ - } while (do_swap || gap > 2); \ - if (gap != 1) __ks_insertsort_##name(a, a + n); \ - } \ - void ks_introsort_##name(size_t n, type_t a[]) \ - { \ - int d; \ - ks_isort_stack_t *top, *stack; \ - type_t rp, swap_tmp; \ - type_t *s, *t, *i, *j, *k; \ - \ - if (n < 1) return; \ - else if (n == 2) { \ - if (__sort_lt(a[1], a[0])) { swap_tmp = a[0]; a[0] = a[1]; a[1] = swap_tmp; } \ - return; \ - } \ - for (d = 2; 1ul<<d < n; ++d); \ - stack = (ks_isort_stack_t*)malloc(sizeof(ks_isort_stack_t) * ((sizeof(size_t)*d)+2)); \ - top = stack; s = a; t = a + (n-1); d <<= 1; \ - while (1) { \ - if (s < t) { \ - if (--d == 0) { \ - ks_combsort_##name(t - s + 1, s); \ - t = s; \ - continue; \ - } \ - i = s; j = t; k = i + ((j-i)>>1) + 1; \ - if (__sort_lt(*k, *i)) { \ - if (__sort_lt(*k, *j)) k = j; \ - } else k = __sort_lt(*j, *i)? i : j; \ - rp = *k; \ - if (k != t) { swap_tmp = *k; *k = *t; *t = swap_tmp; } \ - for (;;) { \ - do ++i; while (__sort_lt(*i, rp)); \ - do --j; while (i <= j && __sort_lt(rp, *j)); \ - if (j <= i) break; \ - swap_tmp = *i; *i = *j; *j = swap_tmp; \ - } \ - swap_tmp = *i; *i = *t; *t = swap_tmp; \ - if (i-s > t-i) { \ - if (i-s > 16) { top->left = s; top->right = i-1; top->depth = d; ++top; } \ - s = t-i > 16? i+1 : t; \ - } else { \ - if (t-i > 16) { top->left = i+1; top->right = t; top->depth = d; ++top; } \ - t = i-s > 16? i-1 : s; \ - } \ - } else { \ - if (top == stack) { \ - free(stack); \ - __ks_insertsort_##name(a, a+n); \ - return; \ - } else { --top; s = (type_t*)top->left; t = (type_t*)top->right; d = top->depth; } \ - } \ - } \ - } \ - /* This function is adapted from: http://ndevilla.free.fr/median/ */ \ - /* 0 <= kk < n */ \ - type_t ks_ksmall_##name(size_t n, type_t arr[], size_t kk) \ - { \ - type_t *low, *high, *k, *ll, *hh, *mid; \ - low = arr; high = arr + n - 1; k = arr + kk; \ - for (;;) { \ - if (high <= low) return *k; \ - if (high == low + 1) { \ - if (__sort_lt(*high, *low)) KSORT_SWAP(type_t, *low, *high); \ - return *k; \ - } \ - mid = low + (high - low) / 2; \ - if (__sort_lt(*high, *mid)) KSORT_SWAP(type_t, *mid, *high); \ - if (__sort_lt(*high, *low)) KSORT_SWAP(type_t, *low, *high); \ - if (__sort_lt(*low, *mid)) KSORT_SWAP(type_t, *mid, *low); \ - KSORT_SWAP(type_t, *mid, *(low+1)); \ - ll = low + 1; hh = high; \ - for (;;) { \ - do ++ll; while (__sort_lt(*ll, *low)); \ - do --hh; while (__sort_lt(*low, *hh)); \ - if (hh < ll) break; \ - KSORT_SWAP(type_t, *ll, *hh); \ - } \ - KSORT_SWAP(type_t, *low, *hh); \ - if (hh <= k) low = ll; \ - if (hh >= k) high = hh - 1; \ - } \ - } \ - void ks_shuffle_##name(size_t n, type_t a[]) \ - { \ - int i, j; \ - for (i = n; i > 1; --i) { \ - type_t tmp; \ - j = (int)(drand48() * i); \ - tmp = a[j]; a[j] = a[i-1]; a[i-1] = tmp; \ - } \ - } \ - void ks_sample_##name(size_t n, size_t r, type_t a[]) /* FIXME: NOT TESTED!!! */ \ - { /* reference: http://code.activestate.com/recipes/272884/ */ \ - int i, k, pop = n; \ - for (i = (int)r, k = 0; i >= 0; --i) { \ - double z = 1., x = drand48(); \ - type_t tmp; \ - while (x < z) z -= z * i / (pop--); \ - if (k != n - pop - 1) tmp = a[k], a[k] = a[n-pop-1], a[n-pop-1] = tmp; \ - ++k; \ - } \ - } - -#define ks_mergesort(name, n, a, t) ks_mergesort_##name(n, a, t) -#define ks_introsort(name, n, a) ks_introsort_##name(n, a) -#define ks_combsort(name, n, a) ks_combsort_##name(n, a) -#define ks_heapsort(name, n, a) ks_heapsort_##name(n, a) -#define ks_heapmake(name, n, a) ks_heapmake_##name(n, a) -#define ks_heapadjust(name, i, n, a) ks_heapadjust_##name(i, n, a) -#define ks_ksmall(name, n, a, k) ks_ksmall_##name(n, a, k) -#define ks_shuffle(name, n, a) ks_shuffle_##name(n, a) - -#define ks_lt_generic(a, b) ((a) < (b)) -#define ks_lt_str(a, b) (strcmp((a), (b)) < 0) - -typedef const char *ksstr_t; - -#define KSORT_INIT_GENERIC(type_t) KSORT_INIT(type_t, type_t, ks_lt_generic) -#define KSORT_INIT_STR KSORT_INIT(str, ksstr_t, ks_lt_str) - -#endif diff --git a/web/server/h2o/libh2o/deps/klib/kstring.c b/web/server/h2o/libh2o/deps/klib/kstring.c deleted file mode 100644 index f0293172a..000000000 --- a/web/server/h2o/libh2o/deps/klib/kstring.c +++ /dev/null @@ -1,229 +0,0 @@ -#include <stdarg.h> -#include <stdio.h> -#include <ctype.h> -#include <string.h> -#include <stdint.h> -#include "kstring.h" - -int kvsprintf(kstring_t *s, const char *fmt, va_list ap) -{ - va_list args; - int l; - va_copy(args, ap); - l = vsnprintf(s->s + s->l, s->m - s->l, fmt, args); // This line does not work with glibc 2.0. See `man snprintf'. - va_end(args); - if (l + 1 > s->m - s->l) { - s->m = s->l + l + 2; - kroundup32(s->m); - s->s = (char*)realloc(s->s, s->m); - va_copy(args, ap); - l = vsnprintf(s->s + s->l, s->m - s->l, fmt, args); - va_end(args); - } - s->l += l; - return l; -} - -int ksprintf(kstring_t *s, const char *fmt, ...) -{ - va_list ap; - int l; - va_start(ap, fmt); - l = kvsprintf(s, fmt, ap); - va_end(ap); - return l; -} - -char *kstrtok(const char *str, const char *sep, ks_tokaux_t *aux) -{ - const char *p, *start; - if (sep) { // set up the table - if (str == 0 && (aux->tab[0]&1)) return 0; // no need to set up if we have finished - aux->finished = 0; - if (sep[1]) { - aux->sep = -1; - aux->tab[0] = aux->tab[1] = aux->tab[2] = aux->tab[3] = 0; - for (p = sep; *p; ++p) aux->tab[*p>>6] |= 1ull<<(*p&0x3f); - } else aux->sep = sep[0]; - } - if (aux->finished) return 0; - else if (str) aux->p = str - 1, aux->finished = 0; - if (aux->sep < 0) { - for (p = start = aux->p + 1; *p; ++p) - if (aux->tab[*p>>6]>>(*p&0x3f)&1) break; - } else { - for (p = start = aux->p + 1; *p; ++p) - if (*p == aux->sep) break; - } - aux->p = p; // end of token - if (*p == 0) aux->finished = 1; // no more tokens - return (char*)start; -} - -// s MUST BE a null terminated string; l = strlen(s) -int ksplit_core(char *s, int delimiter, int *_max, int **_offsets) -{ - int i, n, max, last_char, last_start, *offsets, l; - n = 0; max = *_max; offsets = *_offsets; - l = strlen(s); - -#define __ksplit_aux do { \ - if (_offsets) { \ - s[i] = 0; \ - if (n == max) { \ - int *tmp; \ - max = max? max<<1 : 2; \ - if ((tmp = (int*)realloc(offsets, sizeof(int) * max))) { \ - offsets = tmp; \ - } else { \ - free(offsets); \ - *_offsets = NULL; \ - return 0; \ - } \ - } \ - offsets[n++] = last_start; \ - } else ++n; \ - } while (0) - - for (i = 0, last_char = last_start = 0; i <= l; ++i) { - if (delimiter == 0) { - if (isspace(s[i]) || s[i] == 0) { - if (isgraph(last_char)) __ksplit_aux; // the end of a field - } else { - if (isspace(last_char) || last_char == 0) last_start = i; - } - } else { - if (s[i] == delimiter || s[i] == 0) { - if (last_char != 0 && last_char != delimiter) __ksplit_aux; // the end of a field - } else { - if (last_char == delimiter || last_char == 0) last_start = i; - } - } - last_char = s[i]; - } - *_max = max; *_offsets = offsets; - return n; -} - -/********************** - * Boyer-Moore search * - **********************/ - -typedef unsigned char ubyte_t; - -// reference: http://www-igm.univ-mlv.fr/~lecroq/string/node14.html -static int *ksBM_prep(const ubyte_t *pat, int m) -{ - int i, *suff, *prep, *bmGs, *bmBc; - prep = (int*)calloc(m + 256, sizeof(int)); - bmGs = prep; bmBc = prep + m; - { // preBmBc() - for (i = 0; i < 256; ++i) bmBc[i] = m; - for (i = 0; i < m - 1; ++i) bmBc[pat[i]] = m - i - 1; - } - suff = (int*)calloc(m, sizeof(int)); - { // suffixes() - int f = 0, g; - suff[m - 1] = m; - g = m - 1; - for (i = m - 2; i >= 0; --i) { - if (i > g && suff[i + m - 1 - f] < i - g) - suff[i] = suff[i + m - 1 - f]; - else { - if (i < g) g = i; - f = i; - while (g >= 0 && pat[g] == pat[g + m - 1 - f]) --g; - suff[i] = f - g; - } - } - } - { // preBmGs() - int j = 0; - for (i = 0; i < m; ++i) bmGs[i] = m; - for (i = m - 1; i >= 0; --i) - if (suff[i] == i + 1) - for (; j < m - 1 - i; ++j) - if (bmGs[j] == m) - bmGs[j] = m - 1 - i; - for (i = 0; i <= m - 2; ++i) - bmGs[m - 1 - suff[i]] = m - 1 - i; - } - free(suff); - return prep; -} - -void *kmemmem(const void *_str, int n, const void *_pat, int m, int **_prep) -{ - int i, j, *prep = 0, *bmGs, *bmBc; - const ubyte_t *str, *pat; - str = (const ubyte_t*)_str; pat = (const ubyte_t*)_pat; - prep = (_prep == 0 || *_prep == 0)? ksBM_prep(pat, m) : *_prep; - if (_prep && *_prep == 0) *_prep = prep; - bmGs = prep; bmBc = prep + m; - j = 0; - while (j <= n - m) { - for (i = m - 1; i >= 0 && pat[i] == str[i+j]; --i); - if (i >= 0) { - int max = bmBc[str[i+j]] - m + 1 + i; - if (max < bmGs[i]) max = bmGs[i]; - j += max; - } else return (void*)(str + j); - } - if (_prep == 0) free(prep); - return 0; -} - -char *kstrstr(const char *str, const char *pat, int **_prep) -{ - return (char*)kmemmem(str, strlen(str), pat, strlen(pat), _prep); -} - -char *kstrnstr(const char *str, const char *pat, int n, int **_prep) -{ - return (char*)kmemmem(str, n, pat, strlen(pat), _prep); -} - -/*********************** - * The main() function * - ***********************/ - -#ifdef KSTRING_MAIN -#include <stdio.h> -int main() -{ - kstring_t *s; - int *fields, n, i; - ks_tokaux_t aux; - char *p; - s = (kstring_t*)calloc(1, sizeof(kstring_t)); - // test ksprintf() - ksprintf(s, " abcdefg: %d ", 100); - printf("'%s'\n", s->s); - // test ksplit() - fields = ksplit(s, 0, &n); - for (i = 0; i < n; ++i) - printf("field[%d] = '%s'\n", i, s->s + fields[i]); - // test kstrtok() - s->l = 0; - for (p = kstrtok("ab:cde:fg/hij::k", ":/", &aux); p; p = kstrtok(0, 0, &aux)) { - kputsn(p, aux.p - p, s); - kputc('\n', s); - } - printf("%s", s->s); - // free - free(s->s); free(s); free(fields); - - { - static char *str = "abcdefgcdgcagtcakcdcd"; - static char *pat = "cd"; - char *ret, *s = str; - int *prep = 0; - while ((ret = kstrstr(s, pat, &prep)) != 0) { - printf("match: %s\n", ret); - s = ret + prep[0]; - } - free(prep); - } - return 0; -} -#endif diff --git a/web/server/h2o/libh2o/deps/klib/kstring.h b/web/server/h2o/libh2o/deps/klib/kstring.h deleted file mode 100644 index 0e654cb82..000000000 --- a/web/server/h2o/libh2o/deps/klib/kstring.h +++ /dev/null @@ -1,259 +0,0 @@ -/* The MIT License - - Copyright (c) by Attractive Chaos <attractor@live.co.uk> - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. -*/ - -#ifndef KSTRING_H -#define KSTRING_H - -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> -#include <stdint.h> -#include <stdio.h> - -#ifndef kroundup32 -#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) -#endif - -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4) -#define KS_ATTR_PRINTF(fmt, arg) __attribute__((__format__ (__printf__, fmt, arg))) -#else -#define KS_ATTR_PRINTF(fmt, arg) -#endif - - -/* kstring_t is a simple non-opaque type whose fields are likely to be - * used directly by user code (but see also ks_str() and ks_len() below). - * A kstring_t object is initialised by either of - * kstring_t str = { 0, 0, NULL }; - * kstring_t str; ...; str.l = str.m = 0; str.s = NULL; - * and either ownership of the underlying buffer should be given away before - * the object disappears (i.e., the str.s pointer copied and something else - * responsible for freeing it), or the kstring_t should be destroyed with - * free(str.s); */ -#ifndef KSTRING_T -#define KSTRING_T kstring_t -typedef struct __kstring_t { - size_t l, m; - char *s; -} kstring_t; -#endif - -typedef struct { - uint64_t tab[4]; - int sep, finished; - const char *p; // end of the current token -} ks_tokaux_t; - -#ifdef __cplusplus -extern "C" { -#endif - - int kvsprintf(kstring_t *s, const char *fmt, va_list ap) KS_ATTR_PRINTF(2,0); - int ksprintf(kstring_t *s, const char *fmt, ...) KS_ATTR_PRINTF(2,3); - int ksplit_core(char *s, int delimiter, int *_max, int **_offsets); - char *kstrstr(const char *str, const char *pat, int **_prep); - char *kstrnstr(const char *str, const char *pat, int n, int **_prep); - void *kmemmem(const void *_str, int n, const void *_pat, int m, int **_prep); - - /* kstrtok() is similar to strtok_r() except that str is not - * modified and both str and sep can be NULL. For efficiency, it is - * actually recommended to set both to NULL in the subsequent calls - * if sep is not changed. */ - char *kstrtok(const char *str, const char *sep, ks_tokaux_t *aux); - -#ifdef __cplusplus -} -#endif - -static inline int ks_resize(kstring_t *s, size_t size) -{ - if (s->m < size) { - char *tmp; - s->m = size; - kroundup32(s->m); - if ((tmp = (char*)realloc(s->s, s->m))) - s->s = tmp; - else - return -1; - } - return 0; -} - -static inline char *ks_str(kstring_t *s) -{ - return s->s; -} - -static inline size_t ks_len(kstring_t *s) -{ - return s->l; -} - -static inline int kputsn(const char *p, int l, kstring_t *s) -{ - if (s->l + l + 1 >= s->m) { - char *tmp; - s->m = s->l + l + 2; - kroundup32(s->m); - if ((tmp = (char*)realloc(s->s, s->m))) - s->s = tmp; - else - return EOF; - } - memcpy(s->s + s->l, p, l); - s->l += l; - s->s[s->l] = 0; - return l; -} - -static inline int kputs(const char *p, kstring_t *s) -{ - return kputsn(p, strlen(p), s); -} - -static inline int kputc(int c, kstring_t *s) -{ - if (s->l + 1 >= s->m) { - char *tmp; - s->m = s->l + 2; - kroundup32(s->m); - if ((tmp = (char*)realloc(s->s, s->m))) - s->s = tmp; - else - return EOF; - } - s->s[s->l++] = c; - s->s[s->l] = 0; - return c; -} - -static inline int kputc_(int c, kstring_t *s) -{ - if (s->l + 1 > s->m) { - char *tmp; - s->m = s->l + 1; - kroundup32(s->m); - if ((tmp = (char*)realloc(s->s, s->m))) - s->s = tmp; - else - return EOF; - } - s->s[s->l++] = c; - return 1; -} - -static inline int kputsn_(const void *p, int l, kstring_t *s) -{ - if (s->l + l > s->m) { - char *tmp; - s->m = s->l + l; - kroundup32(s->m); - if ((tmp = (char*)realloc(s->s, s->m))) - s->s = tmp; - else - return EOF; - } - memcpy(s->s + s->l, p, l); - s->l += l; - return l; -} - -static inline int kputw(int c, kstring_t *s) -{ - char buf[16]; - int i, l = 0; - unsigned int x = c; - if (c < 0) x = -x; - do { buf[l++] = x%10 + '0'; x /= 10; } while (x > 0); - if (c < 0) buf[l++] = '-'; - if (s->l + l + 1 >= s->m) { - char *tmp; - s->m = s->l + l + 2; - kroundup32(s->m); - if ((tmp = (char*)realloc(s->s, s->m))) - s->s = tmp; - else - return EOF; - } - for (i = l - 1; i >= 0; --i) s->s[s->l++] = buf[i]; - s->s[s->l] = 0; - return 0; -} - -static inline int kputuw(unsigned c, kstring_t *s) -{ - char buf[16]; - int l, i; - unsigned x; - if (c == 0) return kputc('0', s); - for (l = 0, x = c; x > 0; x /= 10) buf[l++] = x%10 + '0'; - if (s->l + l + 1 >= s->m) { - char *tmp; - s->m = s->l + l + 2; - kroundup32(s->m); - if ((tmp = (char*)realloc(s->s, s->m))) - s->s = tmp; - else - return EOF; - } - for (i = l - 1; i >= 0; --i) s->s[s->l++] = buf[i]; - s->s[s->l] = 0; - return 0; -} - -static inline int kputl(long c, kstring_t *s) -{ - char buf[32]; - int i, l = 0; - unsigned long x = c; - if (c < 0) x = -x; - do { buf[l++] = x%10 + '0'; x /= 10; } while (x > 0); - if (c < 0) buf[l++] = '-'; - if (s->l + l + 1 >= s->m) { - char *tmp; - s->m = s->l + l + 2; - kroundup32(s->m); - if ((tmp = (char*)realloc(s->s, s->m))) - s->s = tmp; - else - return EOF; - } - for (i = l - 1; i >= 0; --i) s->s[s->l++] = buf[i]; - s->s[s->l] = 0; - return 0; -} - -/* - * Returns 's' split by delimiter, with *n being the number of components; - * NULL on failue. - */ -static inline int *ksplit(kstring_t *s, int delimiter, int *n) -{ - int max = 0, *offsets = 0; - *n = ksplit_core(s->s, delimiter, &max, &offsets); - return offsets; -} - -#endif diff --git a/web/server/h2o/libh2o/deps/klib/ksw.c b/web/server/h2o/libh2o/deps/klib/ksw.c deleted file mode 100644 index 742fec90b..000000000 --- a/web/server/h2o/libh2o/deps/klib/ksw.c +++ /dev/null @@ -1,633 +0,0 @@ -/* The MIT License - - Copyright (c) 2011 by Attractive Chaos <attractor@live.co.uk> - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. -*/ - -#include <stdlib.h> -#include <stdint.h> -#include <emmintrin.h> -#include "ksw.h" - -#ifdef __GNUC__ -#define LIKELY(x) __builtin_expect((x),1) -#define UNLIKELY(x) __builtin_expect((x),0) -#else -#define LIKELY(x) (x) -#define UNLIKELY(x) (x) -#endif - -const kswr_t g_defr = { 0, -1, -1, -1, -1, -1, -1 }; - -struct _kswq_t { - int qlen, slen; - uint8_t shift, mdiff, max, size; - __m128i *qp, *H0, *H1, *E, *Hmax; -}; - -/** - * Initialize the query data structure - * - * @param size Number of bytes used to store a score; valid valures are 1 or 2 - * @param qlen Length of the query sequence - * @param query Query sequence - * @param m Size of the alphabet - * @param mat Scoring matrix in a one-dimension array - * - * @return Query data structure - */ -kswq_t *ksw_qinit(int size, int qlen, const uint8_t *query, int m, const int8_t *mat) -{ - kswq_t *q; - int slen, a, tmp, p; - - size = size > 1? 2 : 1; - p = 8 * (3 - size); // # values per __m128i - slen = (qlen + p - 1) / p; // segmented length - q = (kswq_t*)malloc(sizeof(kswq_t) + 256 + 16 * slen * (m + 4)); // a single block of memory - q->qp = (__m128i*)(((size_t)q + sizeof(kswq_t) + 15) >> 4 << 4); // align memory - q->H0 = q->qp + slen * m; - q->H1 = q->H0 + slen; - q->E = q->H1 + slen; - q->Hmax = q->E + slen; - q->slen = slen; q->qlen = qlen; q->size = size; - // compute shift - tmp = m * m; - for (a = 0, q->shift = 127, q->mdiff = 0; a < tmp; ++a) { // find the minimum and maximum score - if (mat[a] < (int8_t)q->shift) q->shift = mat[a]; - if (mat[a] > (int8_t)q->mdiff) q->mdiff = mat[a]; - } - q->max = q->mdiff; - q->shift = 256 - q->shift; // NB: q->shift is uint8_t - q->mdiff += q->shift; // this is the difference between the min and max scores - // An example: p=8, qlen=19, slen=3 and segmentation: - // {{0,3,6,9,12,15,18,-1},{1,4,7,10,13,16,-1,-1},{2,5,8,11,14,17,-1,-1}} - if (size == 1) { - int8_t *t = (int8_t*)q->qp; - for (a = 0; a < m; ++a) { - int i, k, nlen = slen * p; - const int8_t *ma = mat + a * m; - for (i = 0; i < slen; ++i) - for (k = i; k < nlen; k += slen) // p iterations - *t++ = (k >= qlen? 0 : ma[query[k]]) + q->shift; - } - } else { - int16_t *t = (int16_t*)q->qp; - for (a = 0; a < m; ++a) { - int i, k, nlen = slen * p; - const int8_t *ma = mat + a * m; - for (i = 0; i < slen; ++i) - for (k = i; k < nlen; k += slen) // p iterations - *t++ = (k >= qlen? 0 : ma[query[k]]); - } - } - return q; -} - -kswr_t ksw_u8(kswq_t *q, int tlen, const uint8_t *target, int _gapo, int _gape, int xtra) // the first gap costs -(_o+_e) -{ - int slen, i, m_b, n_b, te = -1, gmax = 0, minsc, endsc; - uint64_t *b; - __m128i zero, gapoe, gape, shift, *H0, *H1, *E, *Hmax; - kswr_t r; - -#define __max_16(ret, xx) do { \ - (xx) = _mm_max_epu8((xx), _mm_srli_si128((xx), 8)); \ - (xx) = _mm_max_epu8((xx), _mm_srli_si128((xx), 4)); \ - (xx) = _mm_max_epu8((xx), _mm_srli_si128((xx), 2)); \ - (xx) = _mm_max_epu8((xx), _mm_srli_si128((xx), 1)); \ - (ret) = _mm_extract_epi16((xx), 0) & 0x00ff; \ - } while (0) - - // initialization - r = g_defr; - minsc = (xtra&KSW_XSUBO)? xtra&0xffff : 0x10000; - endsc = (xtra&KSW_XSTOP)? xtra&0xffff : 0x10000; - m_b = n_b = 0; b = 0; - zero = _mm_set1_epi32(0); - gapoe = _mm_set1_epi8(_gapo + _gape); - gape = _mm_set1_epi8(_gape); - shift = _mm_set1_epi8(q->shift); - H0 = q->H0; H1 = q->H1; E = q->E; Hmax = q->Hmax; - slen = q->slen; - for (i = 0; i < slen; ++i) { - _mm_store_si128(E + i, zero); - _mm_store_si128(H0 + i, zero); - _mm_store_si128(Hmax + i, zero); - } - // the core loop - for (i = 0; i < tlen; ++i) { - int j, k, cmp, imax; - __m128i e, h, f = zero, max = zero, *S = q->qp + target[i] * slen; // s is the 1st score vector - h = _mm_load_si128(H0 + slen - 1); // h={2,5,8,11,14,17,-1,-1} in the above example - h = _mm_slli_si128(h, 1); // h=H(i-1,-1); << instead of >> because x64 is little-endian - for (j = 0; LIKELY(j < slen); ++j) { - /* SW cells are computed in the following order: - * H(i,j) = max{H(i-1,j-1)+S(i,j), E(i,j), F(i,j)} - * E(i+1,j) = max{H(i,j)-q, E(i,j)-r} - * F(i,j+1) = max{H(i,j)-q, F(i,j)-r} - */ - // compute H'(i,j); note that at the beginning, h=H'(i-1,j-1) - h = _mm_adds_epu8(h, _mm_load_si128(S + j)); - h = _mm_subs_epu8(h, shift); // h=H'(i-1,j-1)+S(i,j) - e = _mm_load_si128(E + j); // e=E'(i,j) - h = _mm_max_epu8(h, e); - h = _mm_max_epu8(h, f); // h=H'(i,j) - max = _mm_max_epu8(max, h); // set max - _mm_store_si128(H1 + j, h); // save to H'(i,j) - // now compute E'(i+1,j) - h = _mm_subs_epu8(h, gapoe); // h=H'(i,j)-gapo - e = _mm_subs_epu8(e, gape); // e=E'(i,j)-gape - e = _mm_max_epu8(e, h); // e=E'(i+1,j) - _mm_store_si128(E + j, e); // save to E'(i+1,j) - // now compute F'(i,j+1) - f = _mm_subs_epu8(f, gape); - f = _mm_max_epu8(f, h); - // get H'(i-1,j) and prepare for the next j - h = _mm_load_si128(H0 + j); // h=H'(i-1,j) - } - // NB: we do not need to set E(i,j) as we disallow adjecent insertion and then deletion - for (k = 0; LIKELY(k < 16); ++k) { // this block mimics SWPS3; NB: H(i,j) updated in the lazy-F loop cannot exceed max - f = _mm_slli_si128(f, 1); - for (j = 0; LIKELY(j < slen); ++j) { - h = _mm_load_si128(H1 + j); - h = _mm_max_epu8(h, f); // h=H'(i,j) - _mm_store_si128(H1 + j, h); - h = _mm_subs_epu8(h, gapoe); - f = _mm_subs_epu8(f, gape); - cmp = _mm_movemask_epi8(_mm_cmpeq_epi8(_mm_subs_epu8(f, h), zero)); - if (UNLIKELY(cmp == 0xffff)) goto end_loop16; - } - } -end_loop16: - //int k;for (k=0;k<16;++k)printf("%d ", ((uint8_t*)&max)[k]);printf("\n"); - __max_16(imax, max); // imax is the maximum number in max - if (imax >= minsc) { // write the b array; this condition adds branching unfornately - if (n_b == 0 || (int32_t)b[n_b-1] + 1 != i) { // then append - if (n_b == m_b) { - m_b = m_b? m_b<<1 : 8; - b = (uint64_t*)realloc(b, 8 * m_b); - } - b[n_b++] = (uint64_t)imax<<32 | i; - } else if ((int)(b[n_b-1]>>32) < imax) b[n_b-1] = (uint64_t)imax<<32 | i; // modify the last - } - if (imax > gmax) { - gmax = imax; te = i; // te is the end position on the target - for (j = 0; LIKELY(j < slen); ++j) // keep the H1 vector - _mm_store_si128(Hmax + j, _mm_load_si128(H1 + j)); - if (gmax + q->shift >= 255 || gmax >= endsc) break; - } - S = H1; H1 = H0; H0 = S; // swap H0 and H1 - } - r.score = gmax + q->shift < 255? gmax : 255; - r.te = te; - if (r.score != 255) { // get a->qe, the end of query match; find the 2nd best score - int max = -1, low, high, qlen = slen * 16; - uint8_t *t = (uint8_t*)Hmax; - for (i = 0; i < qlen; ++i, ++t) - if ((int)*t > max) max = *t, r.qe = i / 16 + i % 16 * slen; - //printf("%d,%d\n", max, gmax); - if (b) { - i = (r.score + q->max - 1) / q->max; - low = te - i; high = te + i; - for (i = 0; i < n_b; ++i) { - int e = (int32_t)b[i]; - if ((e < low || e > high) && (int)(b[i]>>32) > r.score2) - r.score2 = b[i]>>32, r.te2 = e; - } - } - } - free(b); - return r; -} - -kswr_t ksw_i16(kswq_t *q, int tlen, const uint8_t *target, int _gapo, int _gape, int xtra) // the first gap costs -(_o+_e) -{ - int slen, i, m_b, n_b, te = -1, gmax = 0, minsc, endsc; - uint64_t *b; - __m128i zero, gapoe, gape, *H0, *H1, *E, *Hmax; - kswr_t r; - -#define __max_8(ret, xx) do { \ - (xx) = _mm_max_epi16((xx), _mm_srli_si128((xx), 8)); \ - (xx) = _mm_max_epi16((xx), _mm_srli_si128((xx), 4)); \ - (xx) = _mm_max_epi16((xx), _mm_srli_si128((xx), 2)); \ - (ret) = _mm_extract_epi16((xx), 0); \ - } while (0) - - // initialization - r = g_defr; - minsc = (xtra&KSW_XSUBO)? xtra&0xffff : 0x10000; - endsc = (xtra&KSW_XSTOP)? xtra&0xffff : 0x10000; - m_b = n_b = 0; b = 0; - zero = _mm_set1_epi32(0); - gapoe = _mm_set1_epi16(_gapo + _gape); - gape = _mm_set1_epi16(_gape); - H0 = q->H0; H1 = q->H1; E = q->E; Hmax = q->Hmax; - slen = q->slen; - for (i = 0; i < slen; ++i) { - _mm_store_si128(E + i, zero); - _mm_store_si128(H0 + i, zero); - _mm_store_si128(Hmax + i, zero); - } - // the core loop - for (i = 0; i < tlen; ++i) { - int j, k, imax; - __m128i e, h, f = zero, max = zero, *S = q->qp + target[i] * slen; // s is the 1st score vector - h = _mm_load_si128(H0 + slen - 1); // h={2,5,8,11,14,17,-1,-1} in the above example - h = _mm_slli_si128(h, 2); - for (j = 0; LIKELY(j < slen); ++j) { - h = _mm_adds_epi16(h, *S++); - e = _mm_load_si128(E + j); - h = _mm_max_epi16(h, e); - h = _mm_max_epi16(h, f); - max = _mm_max_epi16(max, h); - _mm_store_si128(H1 + j, h); - h = _mm_subs_epu16(h, gapoe); - e = _mm_subs_epu16(e, gape); - e = _mm_max_epi16(e, h); - _mm_store_si128(E + j, e); - f = _mm_subs_epu16(f, gape); - f = _mm_max_epi16(f, h); - h = _mm_load_si128(H0 + j); - } - for (k = 0; LIKELY(k < 16); ++k) { - f = _mm_slli_si128(f, 2); - for (j = 0; LIKELY(j < slen); ++j) { - h = _mm_load_si128(H1 + j); - h = _mm_max_epi16(h, f); - _mm_store_si128(H1 + j, h); - h = _mm_subs_epu16(h, gapoe); - f = _mm_subs_epu16(f, gape); - if(UNLIKELY(!_mm_movemask_epi8(_mm_cmpgt_epi16(f, h)))) goto end_loop8; - } - } -end_loop8: - __max_8(imax, max); - if (imax >= minsc) { - if (n_b == 0 || (int32_t)b[n_b-1] + 1 != i) { - if (n_b == m_b) { - m_b = m_b? m_b<<1 : 8; - b = (uint64_t*)realloc(b, 8 * m_b); - } - b[n_b++] = (uint64_t)imax<<32 | i; - } else if ((int)(b[n_b-1]>>32) < imax) b[n_b-1] = (uint64_t)imax<<32 | i; // modify the last - } - if (imax > gmax) { - gmax = imax; te = i; - for (j = 0; LIKELY(j < slen); ++j) - _mm_store_si128(Hmax + j, _mm_load_si128(H1 + j)); - if (gmax >= endsc) break; - } - S = H1; H1 = H0; H0 = S; - } - r.score = gmax; r.te = te; - { - int max = -1, low, high, qlen = slen * 8; - uint16_t *t = (uint16_t*)Hmax; - for (i = 0, r.qe = -1; i < qlen; ++i, ++t) - if ((int)*t > max) max = *t, r.qe = i / 8 + i % 8 * slen; - if (b) { - i = (r.score + q->max - 1) / q->max; - low = te - i; high = te + i; - for (i = 0; i < n_b; ++i) { - int e = (int32_t)b[i]; - if ((e < low || e > high) && (int)(b[i]>>32) > r.score2) - r.score2 = b[i]>>32, r.te2 = e; - } - } - } - free(b); - return r; -} - -static void revseq(int l, uint8_t *s) -{ - int i, t; - for (i = 0; i < l>>1; ++i) - t = s[i], s[i] = s[l - 1 - i], s[l - 1 - i] = t; -} - -kswr_t ksw_align(int qlen, uint8_t *query, int tlen, uint8_t *target, int m, const int8_t *mat, int gapo, int gape, int xtra, kswq_t **qry) -{ - int size; - kswq_t *q; - kswr_t r, rr; - kswr_t (*func)(kswq_t*, int, const uint8_t*, int, int, int); - - q = (qry && *qry)? *qry : ksw_qinit((xtra&KSW_XBYTE)? 1 : 2, qlen, query, m, mat); - if (qry && *qry == 0) *qry = q; - func = q->size == 2? ksw_i16 : ksw_u8; - size = q->size; - r = func(q, tlen, target, gapo, gape, xtra); - if (qry == 0) free(q); - if ((xtra&KSW_XSTART) == 0 || ((xtra&KSW_XSUBO) && r.score < (xtra&0xffff))) return r; - revseq(r.qe + 1, query); revseq(r.te + 1, target); // +1 because qe/te points to the exact end, not the position after the end - q = ksw_qinit(size, r.qe + 1, query, m, mat); - rr = func(q, tlen, target, gapo, gape, KSW_XSTOP | r.score); - revseq(r.qe + 1, query); revseq(r.te + 1, target); - free(q); - if (r.score == rr.score) - r.tb = r.te - rr.te, r.qb = r.qe - rr.qe; - return r; -} - -/******************** - *** SW extension *** - ********************/ - -typedef struct { - int32_t h, e; -} eh_t; - -int ksw_extend(int qlen, const uint8_t *query, int tlen, const uint8_t *target, int m, const int8_t *mat, int gapo, int gape, int w, int h0, int *_qle, int *_tle) -{ - eh_t *eh; // score array - int8_t *qp; // query profile - int i, j, k, gapoe = gapo + gape, beg, end, max, max_i, max_j, max_gap; - if (h0 < 0) h0 = 0; - // allocate memory - qp = malloc(qlen * m); - eh = calloc(qlen + 1, 8); - // generate the query profile - for (k = i = 0; k < m; ++k) { - const int8_t *p = &mat[k * m]; - for (j = 0; j < qlen; ++j) qp[i++] = p[query[j]]; - } - // fill the first row - eh[0].h = h0; eh[1].h = h0 > gapoe? h0 - gapoe : 0; - for (j = 2; j <= qlen && eh[j-1].h > gape; ++j) - eh[j].h = eh[j-1].h - gape; - // adjust $w if it is too large - k = m * m; - for (i = 0, max = 0; i < k; ++i) // get the max score - max = max > mat[i]? max : mat[i]; - max_gap = (int)((double)(qlen * max - gapo) / gape + 1.); - max_gap = max_gap > 1? max_gap : 1; - w = w < max_gap? w : max_gap; - // DP loop - max = h0, max_i = max_j = -1; - beg = 0, end = qlen; - for (i = 0; LIKELY(i < tlen); ++i) { - int f = 0, h1, m = 0, mj = -1; - int8_t *q = &qp[target[i] * qlen]; - // compute the first column - h1 = h0 - (gapo + gape * (i + 1)); - if (h1 < 0) h1 = 0; - // apply the band and the constraint (if provided) - if (beg < i - w) beg = i - w; - if (end > i + w + 1) end = i + w + 1; - if (end > qlen) end = qlen; - for (j = beg; LIKELY(j < end); ++j) { - // At the beginning of the loop: eh[j] = { H(i-1,j-1), E(i,j) }, f = F(i,j) and h1 = H(i,j-1) - // Similar to SSE2-SW, cells are computed in the following order: - // H(i,j) = max{H(i-1,j-1)+S(i,j), E(i,j), F(i,j)} - // E(i+1,j) = max{H(i,j)-gapo, E(i,j)} - gape - // F(i,j+1) = max{H(i,j)-gapo, F(i,j)} - gape - eh_t *p = &eh[j]; - int h = p->h, e = p->e; // get H(i-1,j-1) and E(i-1,j) - p->h = h1; // set H(i,j-1) for the next row - h += q[j]; - h = h > e? h : e; - h = h > f? h : f; - h1 = h; // save H(i,j) to h1 for the next column - mj = m > h? mj : j; - m = m > h? m : h; // m is stored at eh[mj+1] - h -= gapoe; - h = h > 0? h : 0; - e -= gape; - e = e > h? e : h; // computed E(i+1,j) - p->e = e; // save E(i+1,j) for the next row - f -= gape; - f = f > h? f : h; // computed F(i,j+1) - } - eh[end].h = h1; eh[end].e = 0; - if (m == 0) break; - if (m > max) max = m, max_i = i, max_j = mj; - // update beg and end for the next round - for (j = mj; j >= beg && eh[j].h; --j); - beg = j + 1; - for (j = mj + 2; j <= end && eh[j].h; ++j); - end = j; - //beg = 0; end = qlen; // uncomment this line for debugging - } - free(eh); free(qp); - if (_qle) *_qle = max_j + 1; - if (_tle) *_tle = max_i + 1; - return max; -} - -/******************** - * Global alignment * - ********************/ - -#define MINUS_INF -0x40000000 - -static inline uint32_t *push_cigar(int *n_cigar, int *m_cigar, uint32_t *cigar, int op, int len) -{ - if (*n_cigar == 0 || op != (cigar[(*n_cigar) - 1]&0xf)) { - if (*n_cigar == *m_cigar) { - *m_cigar = *m_cigar? (*m_cigar)<<1 : 4; - cigar = realloc(cigar, (*m_cigar) << 2); - } - cigar[(*n_cigar)++] = len<<4 | op; - } else cigar[(*n_cigar)-1] += len<<4; - return cigar; -} - -int ksw_global(int qlen, const uint8_t *query, int tlen, const uint8_t *target, int m, const int8_t *mat, int gapo, int gape, int w, int *n_cigar_, uint32_t **cigar_) -{ - eh_t *eh; - int8_t *qp; // query profile - int i, j, k, gapoe = gapo + gape, score, n_col; - uint8_t *z; // backtrack matrix; in each cell: f<<4|e<<2|h; in principle, we can halve the memory, but backtrack will be a little more complex - if (n_cigar_) *n_cigar_ = 0; - // allocate memory - n_col = qlen < 2*w+1? qlen : 2*w+1; // maximum #columns of the backtrack matrix - z = malloc(n_col * tlen); - qp = malloc(qlen * m); - eh = calloc(qlen + 1, 8); - // generate the query profile - for (k = i = 0; k < m; ++k) { - const int8_t *p = &mat[k * m]; - for (j = 0; j < qlen; ++j) qp[i++] = p[query[j]]; - } - // fill the first row - eh[0].h = 0; eh[0].e = MINUS_INF; - for (j = 1; j <= qlen && j <= w; ++j) - eh[j].h = -(gapo + gape * j), eh[j].e = MINUS_INF; - for (; j <= qlen; ++j) eh[j].h = eh[j].e = MINUS_INF; // everything is -inf outside the band - // DP loop - for (i = 0; LIKELY(i < tlen); ++i) { // target sequence is in the outer loop - int32_t f = MINUS_INF, h1, beg, end; - int8_t *q = &qp[target[i] * qlen]; - uint8_t *zi = &z[i * n_col]; - beg = i > w? i - w : 0; - end = i + w + 1 < qlen? i + w + 1 : qlen; // only loop through [beg,end) of the query sequence - h1 = beg == 0? -(gapo + gape * (i + 1)) : MINUS_INF; - for (j = beg; LIKELY(j < end); ++j) { - // This loop is organized in a similar way to ksw_extend() and ksw_sse2(), except: - // 1) not checking h>0; 2) recording direction for backtracking - eh_t *p = &eh[j]; - int32_t h = p->h, e = p->e; - uint8_t d; // direction - p->h = h1; - h += q[j]; - d = h > e? 0 : 1; - h = h > e? h : e; - d = h > f? d : 2; - h = h > f? h : f; - h1 = h; - h -= gapoe; - e -= gape; - d |= e > h? 1<<2 : 0; - e = e > h? e : h; - p->e = e; - f -= gape; - d |= f > h? 2<<4 : 0; // if we want to halve the memory, use one bit only, instead of two - f = f > h? f : h; - zi[j - beg] = d; // z[i,j] keeps h for the current cell and e/f for the next cell - } - eh[end].h = h1; eh[end].e = MINUS_INF; - } - score = eh[qlen].h; - if (n_cigar_ && cigar_) { // backtrack - int n_cigar = 0, m_cigar = 0, which = 0; - uint32_t *cigar = 0, tmp; - i = tlen - 1; k = (i + w + 1 < qlen? i + w + 1 : qlen) - 1; // (i,k) points to the last cell - while (i >= 0 && k >= 0) { - which = z[i * n_col + (k - (i > w? i - w : 0))] >> (which<<1) & 3; - if (which == 0) cigar = push_cigar(&n_cigar, &m_cigar, cigar, 0, 1), --i, --k; - else if (which == 1) cigar = push_cigar(&n_cigar, &m_cigar, cigar, 2, 1), --i; - else cigar = push_cigar(&n_cigar, &m_cigar, cigar, 1, 1), --k; - } - if (i >= 0) cigar = push_cigar(&n_cigar, &m_cigar, cigar, 2, i + 1); - if (k >= 0) cigar = push_cigar(&n_cigar, &m_cigar, cigar, 1, k + 1); - for (i = 0; i < n_cigar>>1; ++i) // reverse CIGAR - tmp = cigar[i], cigar[i] = cigar[n_cigar-1-i], cigar[n_cigar-1-i] = tmp; - *n_cigar_ = n_cigar, *cigar_ = cigar; - } - free(eh); free(qp); free(z); - return score; -} - -/******************************************* - * Main function (not compiled by default) * - *******************************************/ - -#ifdef _KSW_MAIN - -#include <unistd.h> -#include <stdio.h> -#include <zlib.h> -#include "kseq.h" -KSEQ_INIT(gzFile, gzread) - -unsigned char seq_nt4_table[256] = { - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 0, 4, 1, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 0, 4, 1, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 -}; - -int main(int argc, char *argv[]) -{ - int c, sa = 1, sb = 3, i, j, k, forward_only = 0, max_rseq = 0; - int8_t mat[25]; - int gapo = 5, gape = 2, minsc = 0, xtra = KSW_XSTART; - uint8_t *rseq = 0; - gzFile fpt, fpq; - kseq_t *kst, *ksq; - - // parse command line - while ((c = getopt(argc, argv, "a:b:q:r:ft:1")) >= 0) { - switch (c) { - case 'a': sa = atoi(optarg); break; - case 'b': sb = atoi(optarg); break; - case 'q': gapo = atoi(optarg); break; - case 'r': gape = atoi(optarg); break; - case 't': minsc = atoi(optarg); break; - case 'f': forward_only = 1; break; - case '1': xtra |= KSW_XBYTE; break; - } - } - if (optind + 2 > argc) { - fprintf(stderr, "Usage: ksw [-1] [-f] [-a%d] [-b%d] [-q%d] [-r%d] [-t%d] <target.fa> <query.fa>\n", sa, sb, gapo, gape, minsc); - return 1; - } - if (minsc > 0xffff) minsc = 0xffff; - xtra |= KSW_XSUBO | minsc; - // initialize scoring matrix - for (i = k = 0; i < 4; ++i) { - for (j = 0; j < 4; ++j) - mat[k++] = i == j? sa : -sb; - mat[k++] = 0; // ambiguous base - } - for (j = 0; j < 5; ++j) mat[k++] = 0; - // open file - fpt = gzopen(argv[optind], "r"); kst = kseq_init(fpt); - fpq = gzopen(argv[optind+1], "r"); ksq = kseq_init(fpq); - // all-pair alignment - while (kseq_read(ksq) > 0) { - kswq_t *q[2] = {0, 0}; - kswr_t r; - for (i = 0; i < (int)ksq->seq.l; ++i) ksq->seq.s[i] = seq_nt4_table[(int)ksq->seq.s[i]]; - if (!forward_only) { // reverse - if ((int)ksq->seq.m > max_rseq) { - max_rseq = ksq->seq.m; - rseq = (uint8_t*)realloc(rseq, max_rseq); - } - for (i = 0, j = ksq->seq.l - 1; i < (int)ksq->seq.l; ++i, --j) - rseq[j] = ksq->seq.s[i] == 4? 4 : 3 - ksq->seq.s[i]; - } - gzrewind(fpt); kseq_rewind(kst); - while (kseq_read(kst) > 0) { - for (i = 0; i < (int)kst->seq.l; ++i) kst->seq.s[i] = seq_nt4_table[(int)kst->seq.s[i]]; - r = ksw_align(ksq->seq.l, (uint8_t*)ksq->seq.s, kst->seq.l, (uint8_t*)kst->seq.s, 5, mat, gapo, gape, xtra, &q[0]); - if (r.score >= minsc) - printf("%s\t%d\t%d\t%s\t%d\t%d\t%d\t%d\t%d\n", kst->name.s, r.tb, r.te+1, ksq->name.s, r.qb, r.qe+1, r.score, r.score2, r.te2); - if (rseq) { - r = ksw_align(ksq->seq.l, rseq, kst->seq.l, (uint8_t*)kst->seq.s, 5, mat, gapo, gape, xtra, &q[1]); - if (r.score >= minsc) - printf("%s\t%d\t%d\t%s\t%d\t%d\t%d\t%d\t%d\n", kst->name.s, r.tb, r.te+1, ksq->name.s, (int)ksq->seq.l - r.qb, (int)ksq->seq.l - 1 - r.qe, r.score, r.score2, r.te2); - } - } - free(q[0]); free(q[1]); - } - free(rseq); - kseq_destroy(kst); gzclose(fpt); - kseq_destroy(ksq); gzclose(fpq); - return 0; -} -#endif diff --git a/web/server/h2o/libh2o/deps/klib/ksw.h b/web/server/h2o/libh2o/deps/klib/ksw.h deleted file mode 100644 index 5162dc03d..000000000 --- a/web/server/h2o/libh2o/deps/klib/ksw.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef __AC_KSW_H -#define __AC_KSW_H - -#include <stdint.h> - -#define KSW_XBYTE 0x10000 -#define KSW_XSTOP 0x20000 -#define KSW_XSUBO 0x40000 -#define KSW_XSTART 0x80000 - -struct _kswq_t; -typedef struct _kswq_t kswq_t; - -typedef struct { - int score; // best score - int te, qe; // target end and query end - int score2, te2; // second best score and ending position on the target - int tb, qb; // target start and query start -} kswr_t; - -#ifdef __cplusplus -extern "C" { -#endif - - /** - * Aligning two sequences - * - * @param qlen length of the query sequence (typically <tlen) - * @param query query sequence with 0 <= query[i] < m - * @param tlen length of the target sequence - * @param target target sequence - * @param m number of residue types - * @param mat m*m scoring matrix in one-dimention array - * @param gapo gap open penalty; a gap of length l cost "-(gapo+l*gape)" - * @param gape gap extension penalty - * @param xtra extra information (see below) - * @param qry query profile (see below) - * - * @return alignment information in a struct; unset values to -1 - * - * When xtra==0, ksw_align() uses a signed two-byte integer to store a - * score and only finds the best score and the end positions. The 2nd best - * score or the start positions are not attempted. The default behavior can - * be tuned by setting KSW_X* flags: - * - * KSW_XBYTE: use an unsigned byte to store a score. If overflow occurs, - * kswr_t::score will be set to 255 - * - * KSW_XSUBO: track the 2nd best score and the ending position on the - * target if the 2nd best is higher than (xtra&0xffff) - * - * KSW_XSTOP: stop if the maximum score is above (xtra&0xffff) - * - * KSW_XSTART: find the start positions - * - * When *qry==NULL, ksw_align() will compute and allocate the query profile - * and when the function returns, *qry will point to the profile, which can - * be deallocated simply by free(). If one query is aligned against multiple - * target sequences, *qry should be set to NULL during the first call and - * freed after the last call. Note that qry can equal 0. In this case, the - * query profile will be deallocated in ksw_align(). - */ - kswr_t ksw_align(int qlen, uint8_t *query, int tlen, uint8_t *target, int m, const int8_t *mat, int gapo, int gape, int xtra, kswq_t **qry); - - int ksw_extend(int qlen, const uint8_t *query, int tlen, const uint8_t *target, int m, const int8_t *mat, int gapo, int gape, int w, int h0, int *_qle, int *_tle); - int ksw_global(int qlen, const uint8_t *query, int tlen, const uint8_t *target, int m, const int8_t *mat, int gapo, int gape, int w, int *_n_cigar, uint32_t **_cigar); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/web/server/h2o/libh2o/deps/klib/kthread.c b/web/server/h2o/libh2o/deps/klib/kthread.c deleted file mode 100644 index 80f84cb35..000000000 --- a/web/server/h2o/libh2o/deps/klib/kthread.c +++ /dev/null @@ -1,143 +0,0 @@ -#include <pthread.h> -#include <stdlib.h> -#include <limits.h> - -/************ - * kt_for() * - ************/ - -struct kt_for_t; - -typedef struct { - struct kt_for_t *t; - long i; -} ktf_worker_t; - -typedef struct kt_for_t { - int n_threads; - long n; - ktf_worker_t *w; - void (*func)(void*,long,int); - void *data; -} kt_for_t; - -static inline long steal_work(kt_for_t *t) -{ - int i, min_i = -1; - long k, min = LONG_MAX; - for (i = 0; i < t->n_threads; ++i) - if (min > t->w[i].i) min = t->w[i].i, min_i = i; - k = __sync_fetch_and_add(&t->w[min_i].i, t->n_threads); - return k >= t->n? -1 : k; -} - -static void *ktf_worker(void *data) -{ - ktf_worker_t *w = (ktf_worker_t*)data; - long i; - for (;;) { - i = __sync_fetch_and_add(&w->i, w->t->n_threads); - if (i >= w->t->n) break; - w->t->func(w->t->data, i, w - w->t->w); - } - while ((i = steal_work(w->t)) >= 0) - w->t->func(w->t->data, i, w - w->t->w); - pthread_exit(0); -} - -void kt_for(int n_threads, void (*func)(void*,long,int), void *data, long n) -{ - int i; - kt_for_t t; - pthread_t *tid; - t.func = func, t.data = data, t.n_threads = n_threads, t.n = n; - t.w = (ktf_worker_t*)alloca(n_threads * sizeof(ktf_worker_t)); - tid = (pthread_t*)alloca(n_threads * sizeof(pthread_t)); - for (i = 0; i < n_threads; ++i) - t.w[i].t = &t, t.w[i].i = i; - for (i = 0; i < n_threads; ++i) pthread_create(&tid[i], 0, ktf_worker, &t.w[i]); - for (i = 0; i < n_threads; ++i) pthread_join(tid[i], 0); -} - -/***************** - * kt_pipeline() * - *****************/ - -struct ktp_t; - -typedef struct { - struct ktp_t *pl; - int step, running; - void *data; -} ktp_worker_t; - -typedef struct ktp_t { - void *shared; - void *(*func)(void*, int, void*); - int n_workers, n_steps; - ktp_worker_t *workers; - pthread_mutex_t mutex; - pthread_cond_t cv; -} ktp_t; - -static void *ktp_worker(void *data) -{ - ktp_worker_t *w = (ktp_worker_t*)data; - ktp_t *p = w->pl; - while (w->step < p->n_steps) { - // test whether we can kick off the job with this worker - pthread_mutex_lock(&p->mutex); - for (;;) { - int i; - // test whether another worker is doing the same step - for (i = 0; i < p->n_workers; ++i) { - if (w == &p->workers[i]) continue; // ignore itself - if (p->workers[i].running && p->workers[i].step == w->step) - break; - } - if (i == p->n_workers) break; // no other workers doing w->step; then this worker will - pthread_cond_wait(&p->cv, &p->mutex); - } - w->running = 1; - pthread_mutex_unlock(&p->mutex); - - // working on w->step - w->data = p->func(p->shared, w->step, w->step? w->data : 0); // for the first step, input is NULL - - // update step and let other workers know - pthread_mutex_lock(&p->mutex); - w->step = w->step == p->n_steps - 1 || w->data? (w->step + 1) % p->n_steps : p->n_steps; - w->running = 0; - pthread_cond_broadcast(&p->cv); - pthread_mutex_unlock(&p->mutex); - } - pthread_exit(0); -} - -void kt_pipeline(int n_threads, void *(*func)(void*, int, void*), void *shared_data, int n_steps) -{ - ktp_t aux; - pthread_t *tid; - int i; - - if (n_threads < 1) n_threads = 1; - aux.n_workers = n_threads; - aux.n_steps = n_steps; - aux.func = func; - aux.shared = shared_data; - pthread_mutex_init(&aux.mutex, 0); - pthread_cond_init(&aux.cv, 0); - - aux.workers = alloca(n_threads * sizeof(ktp_worker_t)); - for (i = 0; i < n_threads; ++i) { - ktp_worker_t *w = &aux.workers[i]; - w->step = w->running = 0; w->pl = &aux; w->data = 0; - } - - tid = alloca(n_threads * sizeof(pthread_t)); - for (i = 0; i < n_threads; ++i) pthread_create(&tid[i], 0, ktp_worker, &aux.workers[i]); - for (i = 0; i < n_threads; ++i) pthread_join(tid[i], 0); - - pthread_mutex_destroy(&aux.mutex); - pthread_cond_destroy(&aux.cv); -} diff --git a/web/server/h2o/libh2o/deps/klib/kurl.c b/web/server/h2o/libh2o/deps/klib/kurl.c deleted file mode 100644 index 3bf92901c..000000000 --- a/web/server/h2o/libh2o/deps/klib/kurl.c +++ /dev/null @@ -1,583 +0,0 @@ -#include <stdio.h> -#include <fcntl.h> -#include <ctype.h> -#include <assert.h> -#include <stdint.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <curl/curl.h> -#include "kurl.h" - -/********************** - *** Core kurl APIs *** - **********************/ - -#define KU_DEF_BUFLEN 0x8000 -#define KU_MAX_SKIP (KU_DEF_BUFLEN<<1) // if seek step is smaller than this, skip - -#define kurl_isfile(u) ((u)->fd >= 0) - -#ifndef kroundup32 -#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) -#endif - -struct kurl_t { - CURLM *multi; // cURL multi handler - CURL *curl; // cURL easy handle - uint8_t *buf; // buffer - off_t off0; // offset of the first byte in the buffer; the actual file offset equals off0 + p_buf - int fd; // file descriptor for a normal file; <0 for a remote file - int m_buf; // max buffer size; for a remote file, CURL_MAX_WRITE_SIZE*2 is recommended - int l_buf; // length of the buffer; l_buf == 0 iff the input read entirely; l_buf <= m_buf - int p_buf; // file position in the buffer; p_buf <= l_buf - int done_reading; // true if we can read nothing from the file; buffer may not be empty even if done_reading is set - int err; // error code - struct curl_slist *hdr; -}; - -typedef struct { - char *url, *date, *auth; -} s3aux_t; - -int kurl_init(void) // required for SSL and win32 socket; NOT thread safe -{ - return curl_global_init(CURL_GLOBAL_DEFAULT); -} - -void kurl_destroy(void) -{ - curl_global_cleanup(); -} - -static int prepare(kurl_t *ku, int do_seek) -{ - if (kurl_isfile(ku)) { - if (do_seek && lseek(ku->fd, ku->off0, SEEK_SET) != ku->off0) - return -1; - } else { // FIXME: for S3, we need to re-authorize - int rc; - rc = curl_multi_remove_handle(ku->multi, ku->curl); - rc = curl_easy_setopt(ku->curl, CURLOPT_RESUME_FROM, ku->off0); - rc = curl_multi_add_handle(ku->multi, ku->curl); - } - ku->p_buf = ku->l_buf = 0; // empty the buffer - return 0; -} - -static size_t write_cb(char *ptr, size_t size, size_t nmemb, void *data) // callback required by cURL -{ - kurl_t *ku = (kurl_t*)data; - ssize_t nbytes = size * nmemb; - if (nbytes + ku->l_buf > ku->m_buf) - return CURL_WRITEFUNC_PAUSE; - memcpy(ku->buf + ku->l_buf, ptr, nbytes); - ku->l_buf += nbytes; - return nbytes; -} - -static int fill_buffer(kurl_t *ku) // fill the buffer -{ - assert(ku->p_buf == ku->l_buf); // buffer is always used up when fill_buffer() is called; otherwise a bug - ku->off0 += ku->l_buf; - ku->p_buf = ku->l_buf = 0; - if (ku->done_reading) return 0; - if (kurl_isfile(ku)) { - // The following block is equivalent to "ku->l_buf = read(ku->fd, ku->buf, ku->m_buf)" on Mac. - // On Linux, the man page does not specify whether read() guarantees to read ku->m_buf bytes - // even if ->fd references a normal file with sufficient remaining bytes. - while (ku->l_buf < ku->m_buf) { - int l; - l = read(ku->fd, ku->buf + ku->l_buf, ku->m_buf - ku->l_buf); - if (l == 0) break; - ku->l_buf += l; - } - if (ku->l_buf < ku->m_buf) ku->done_reading = 1; - } else { - int n_running, rc; - fd_set fdr, fdw, fde; - do { - int maxfd = -1; - long curl_to = -1; - struct timeval to; - // the following is adaped from docs/examples/fopen.c - to.tv_sec = 10, to.tv_usec = 0; // 10 seconds - curl_multi_timeout(ku->multi, &curl_to); - if (curl_to >= 0) { - to.tv_sec = curl_to / 1000; - if (to.tv_sec > 1) to.tv_sec = 1; - else to.tv_usec = (curl_to % 1000) * 1000; - } - FD_ZERO(&fdr); FD_ZERO(&fdw); FD_ZERO(&fde); - curl_multi_fdset(ku->multi, &fdr, &fdw, &fde, &maxfd); // FIXME: check return code - if (maxfd >= 0 && (rc = select(maxfd+1, &fdr, &fdw, &fde, &to)) < 0) break; - if (maxfd < 0) { // check curl_multi_fdset.3 about why we wait for 100ms here - struct timespec req, rem; - req.tv_sec = 0; req.tv_nsec = 100000000; // this is 100ms - nanosleep(&req, &rem); - } - curl_easy_pause(ku->curl, CURLPAUSE_CONT); - rc = curl_multi_perform(ku->multi, &n_running); // FIXME: check return code - } while (n_running && ku->l_buf < ku->m_buf - CURL_MAX_WRITE_SIZE); - if (ku->l_buf < ku->m_buf - CURL_MAX_WRITE_SIZE) ku->done_reading = 1; - } - return ku->l_buf; -} - -int kurl_close(kurl_t *ku) -{ - if (ku == 0) return 0; - if (ku->fd < 0) { - curl_multi_remove_handle(ku->multi, ku->curl); - curl_easy_cleanup(ku->curl); - curl_multi_cleanup(ku->multi); - if (ku->hdr) curl_slist_free_all(ku->hdr); - } else close(ku->fd); - free(ku->buf); - free(ku); - return 0; -} - -kurl_t *kurl_open(const char *url, kurl_opt_t *opt) -{ - extern s3aux_t s3_parse(const char *url, const char *_id, const char *_secret, const char *fn); - const char *p, *q; - kurl_t *ku; - int fd = -1, is_file = 1, failed = 0; - - p = strstr(url, "://"); - if (p && *p) { - for (q = url; q != p; ++q) - if (!isalnum(*q)) break; - if (q == p) is_file = 0; - } - if (is_file && (fd = open(url, O_RDONLY)) < 0) return 0; - - ku = (kurl_t*)calloc(1, sizeof(kurl_t)); - ku->fd = is_file? fd : -1; - if (!kurl_isfile(ku)) { - ku->multi = curl_multi_init(); - ku->curl = curl_easy_init(); - if (strstr(url, "s3://") == url) { - s3aux_t a; - a = s3_parse(url, (opt? opt->s3keyid : 0), (opt? opt->s3secretkey : 0), (opt? opt->s3key_fn : 0)); - if (a.url == 0 || a.date == 0 || a.auth == 0) { - kurl_close(ku); - return 0; - } - ku->hdr = curl_slist_append(ku->hdr, a.date); - ku->hdr = curl_slist_append(ku->hdr, a.auth); - curl_easy_setopt(ku->curl, CURLOPT_URL, a.url); - curl_easy_setopt(ku->curl, CURLOPT_HTTPHEADER, ku->hdr); - free(a.date); free(a.auth); free(a.url); - } else curl_easy_setopt(ku->curl, CURLOPT_URL, url); - curl_easy_setopt(ku->curl, CURLOPT_WRITEDATA, ku); - curl_easy_setopt(ku->curl, CURLOPT_VERBOSE, 0L); - curl_easy_setopt(ku->curl, CURLOPT_NOSIGNAL, 1L); - curl_easy_setopt(ku->curl, CURLOPT_WRITEFUNCTION, write_cb); - curl_easy_setopt(ku->curl, CURLOPT_SSL_VERIFYPEER, 0L); - curl_easy_setopt(ku->curl, CURLOPT_SSL_VERIFYHOST, 0L); - curl_easy_setopt(ku->curl, CURLOPT_FOLLOWLOCATION, 1L); - } - ku->m_buf = KU_DEF_BUFLEN; - if (!kurl_isfile(ku) && ku->m_buf < CURL_MAX_WRITE_SIZE * 2) - ku->m_buf = CURL_MAX_WRITE_SIZE * 2; // for remote files, the buffer set to 2*CURL_MAX_WRITE_SIZE - ku->buf = (uint8_t*)calloc(ku->m_buf, 1); - if (kurl_isfile(ku)) failed = (fill_buffer(ku) <= 0); - else failed = (prepare(ku, 0) < 0 || fill_buffer(ku) <= 0); - if (failed) { - kurl_close(ku); - return 0; - } - return ku; -} - -kurl_t *kurl_dopen(int fd) -{ - kurl_t *ku; - ku = (kurl_t*)calloc(1, sizeof(kurl_t)); - ku->fd = fd; - ku->m_buf = KU_DEF_BUFLEN; - ku->buf = (uint8_t*)calloc(ku->m_buf, 1); - if (prepare(ku, 0) < 0 || fill_buffer(ku) <= 0) { - kurl_close(ku); - return 0; - } - return ku; -} - -int kurl_buflen(kurl_t *ku, int len) -{ - if (len <= 0 || len < ku->l_buf) return ku->m_buf; - if (!kurl_isfile(ku) && len < CURL_MAX_WRITE_SIZE * 2) return ku->m_buf; - ku->m_buf = len; - kroundup32(ku->m_buf); - ku->buf = (uint8_t*)realloc(ku->buf, ku->m_buf); - return ku->m_buf; -} - -ssize_t kurl_read(kurl_t *ku, void *buf, size_t nbytes) -{ - ssize_t rest = nbytes; - if (ku->l_buf == 0) return 0; // end-of-file - while (rest) { - if (ku->l_buf - ku->p_buf >= rest) { - if (buf) memcpy((uint8_t*)buf + (nbytes - rest), ku->buf + ku->p_buf, rest); - ku->p_buf += rest; - rest = 0; - } else { - int ret; - if (buf && ku->l_buf > ku->p_buf) - memcpy((uint8_t*)buf + (nbytes - rest), ku->buf + ku->p_buf, ku->l_buf - ku->p_buf); - rest -= ku->l_buf - ku->p_buf; - ku->p_buf = ku->l_buf; - ret = fill_buffer(ku); - if (ret <= 0) break; - } - } - return nbytes - rest; -} - -off_t kurl_seek(kurl_t *ku, off_t offset, int whence) // FIXME: sometimes when seek() fails, read() will fail as well. -{ - off_t new_off = -1, cur_off; - int failed = 0, seek_end = 0; - if (ku == 0) return -1; - cur_off = ku->off0 + ku->p_buf; - if (whence == SEEK_SET) new_off = offset; - else if (whence == SEEK_CUR) new_off += cur_off + offset; - else if (whence == SEEK_END && kurl_isfile(ku)) new_off = lseek(ku->fd, offset, SEEK_END), seek_end = 1; - else { // not supported whence - ku->err = KURL_INV_WHENCE; - return -1; - } - if (new_off < 0) { // negtive absolute offset - ku->err = KURL_SEEK_OUT; - return -1; - } - if (!seek_end && new_off >= cur_off && new_off - cur_off + ku->p_buf < ku->l_buf) { - ku->p_buf += new_off - cur_off; - return ku->off0 + ku->p_buf; - } - if (seek_end || new_off < cur_off || new_off - cur_off > KU_MAX_SKIP) { // if jump is large, do actual seek - ku->off0 = new_off; - ku->done_reading = 0; - if (prepare(ku, 1) < 0 || fill_buffer(ku) <= 0) failed = 1; - } else { // if jump is small, read through - off_t r; - r = kurl_read(ku, 0, new_off - cur_off); - if (r + cur_off != new_off) failed = 1; // out of range - } - if (failed) ku->err = KURL_SEEK_OUT, ku->l_buf = ku->p_buf = 0, new_off = -1; - return new_off; -} - -off_t kurl_tell(const kurl_t *ku) -{ - if (ku == 0) return -1; - return ku->off0 + ku->p_buf; -} - -int kurl_eof(const kurl_t *ku) -{ - if (ku == 0) return 1; - return (ku->l_buf == 0); // unless file end, buffer should never be empty -} - -int kurl_fileno(const kurl_t *ku) -{ - if (ku == 0) return -1; - return ku->fd; -} - -int kurl_error(const kurl_t *ku) -{ - if (ku == 0) return KURL_NULL; - return ku->err; -} - -/***************** - *** HMAC-SHA1 *** - *****************/ - -/* This code is public-domain - it is based on libcrypt placed in the public domain by Wei Dai and other contributors. */ - -#define HASH_LENGTH 20 -#define BLOCK_LENGTH 64 - -typedef struct sha1nfo { - union { uint8_t b[BLOCK_LENGTH]; uint32_t w[BLOCK_LENGTH/4]; } buf; - uint8_t bufOffset; - union { uint8_t b[HASH_LENGTH]; uint32_t w[HASH_LENGTH/4]; } state; - uint32_t byteCount; - uint8_t keyBuffer[BLOCK_LENGTH]; - uint8_t innerHash[HASH_LENGTH]; -} sha1nfo; - -void sha1_init(sha1nfo *s) -{ - const uint8_t table[] = { 0x01,0x23,0x45,0x67, 0x89,0xab,0xcd,0xef, 0xfe,0xdc,0xba,0x98, 0x76,0x54,0x32,0x10, 0xf0,0xe1,0xd2,0xc3 }; - memcpy(s->state.b, table, HASH_LENGTH); - s->byteCount = 0; - s->bufOffset = 0; -} - -#define rol32(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) - -static void sha1_hashBlock(sha1nfo *s) -{ - uint32_t i, t, a = s->state.w[0], b = s->state.w[1], c = s->state.w[2], d = s->state.w[3], e = s->state.w[4]; - for (i = 0; i < 80; i++) { - if (i >= 16) { - t = s->buf.w[(i+13)&15] ^ s->buf.w[(i+8)&15] ^ s->buf.w[(i+2)&15] ^ s->buf.w[i&15]; - s->buf.w[i&15] = rol32(t, 1); - } - if (i < 20) t = 0x5a827999 + (d ^ (b & (c ^ d))); - else if (i < 40) t = 0x6ed9eba1 + (b ^ c ^ d); - else if (i < 60) t = 0x8f1bbcdc + ((b & c) | (d & (b | c))); - else t = 0xca62c1d6 + (b ^ c ^ d); - t += rol32(a, 5) + e + s->buf.w[i&15]; - e = d; d = c; c = rol32(b, 30); b = a; a = t; - } - s->state.w[0] += a; s->state.w[1] += b; s->state.w[2] += c; s->state.w[3] += d; s->state.w[4] += e; -} - -static inline void sha1_add(sha1nfo *s, uint8_t data) -{ - s->buf.b[s->bufOffset ^ 3] = data; - if (++s->bufOffset == BLOCK_LENGTH) { - sha1_hashBlock(s); - s->bufOffset = 0; - } -} - -void sha1_write1(sha1nfo *s, uint8_t data) -{ - ++s->byteCount; - sha1_add(s, data); -} - -void sha1_write(sha1nfo *s, const char *data, size_t len) -{ - while (len--) sha1_write1(s, (uint8_t)*data++); -} - -const uint8_t *sha1_final(sha1nfo *s) -{ - int i; - sha1_add(s, 0x80); - while (s->bufOffset != 56) sha1_add(s, 0); - sha1_add(s, 0); - sha1_add(s, 0); - sha1_add(s, 0); - sha1_add(s, s->byteCount >> 29); - sha1_add(s, s->byteCount >> 21); - sha1_add(s, s->byteCount >> 13); - sha1_add(s, s->byteCount >> 5); - sha1_add(s, s->byteCount << 3); - for (i = 0; i < 5; ++i) { - uint32_t a = s->state.w[i]; - s->state.w[i] = a<<24 | (a<<8&0x00ff0000) | (a>>8&0x0000ff00) | a>>24; - } - return s->state.b; -} - -#define HMAC_IPAD 0x36 -#define HMAC_OPAD 0x5c - -void sha1_init_hmac(sha1nfo *s, const uint8_t* key, int l_key) -{ - uint8_t i; - memset(s->keyBuffer, 0, BLOCK_LENGTH); - if (l_key > BLOCK_LENGTH) { - sha1_init(s); - while (l_key--) sha1_write1(s, *key++); - memcpy(s->keyBuffer, sha1_final(s), HASH_LENGTH); - } else memcpy(s->keyBuffer, key, l_key); - sha1_init(s); - for (i = 0; i < BLOCK_LENGTH; ++i) - sha1_write1(s, s->keyBuffer[i] ^ HMAC_IPAD); -} - -const uint8_t *sha1_final_hmac(sha1nfo *s) -{ - uint8_t i; - memcpy(s->innerHash, sha1_final(s), HASH_LENGTH); - sha1_init(s); - for (i = 0; i < BLOCK_LENGTH; ++i) sha1_write1(s, s->keyBuffer[i] ^ HMAC_OPAD); - for (i = 0; i < HASH_LENGTH; ++i) sha1_write1(s, s->innerHash[i]); - return sha1_final(s); -} - -/******************* - *** S3 protocol *** - *******************/ - -#include <time.h> -#include <ctype.h> - -static void s3_sign(const char *key, const char *data, char out[29]) -{ - const char *b64tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - const uint8_t *digest; - int i, j, rest; - sha1nfo s; - sha1_init_hmac(&s, (uint8_t*)key, strlen(key)); - sha1_write(&s, data, strlen(data)); - digest = sha1_final_hmac(&s); - for (j = i = 0, rest = 8; i < 20; ++j) { // base64 encoding - if (rest <= 6) { - int next = i < 19? digest[i+1] : 0; - out[j] = b64tab[(int)(digest[i] << (6-rest) & 0x3f) | next >> (rest+2)], ++i, rest += 2; - } else out[j] = b64tab[(int)digest[i] >> (rest-6) & 0x3f], rest -= 6; - } - out[j++] = '='; out[j] = 0; // SHA1 digest always has 160 bits, or 20 bytes. We need one '=' at the end. -} - -static char *s3_read_awssecret(const char *fn) -{ - char *p, *secret, buf[128], *path; - FILE *fp; - int l; - if (fn == 0) { - char *home; - home = getenv("HOME"); - if (home == 0) return 0; - l = strlen(home) + 12; - path = (char*)malloc(strlen(home) + 12); - strcat(strcpy(path, home), "/.awssecret"); - } else path = (char*)fn; - fp = fopen(path, "r"); - if (path != fn) free(path); - if (fp == 0) return 0; - l = fread(buf, 1, 127, fp); - fclose(fp); - buf[l] = 0; - for (p = buf; *p != 0 && *p != '\n'; ++p); - if (*p == 0) return 0; - *p = 0; secret = p + 1; - for (++p; *p != 0 && *p != '\n'; ++p); - *p = 0; - l = p - buf + 1; - p = (char*)malloc(l); - memcpy(p, buf, l); - return p; -} - -typedef struct { int l, m; char *s; } kstring_t; - -static inline int kputsn(const char *p, int l, kstring_t *s) -{ - if (s->l + l + 1 >= s->m) { - s->m = s->l + l + 2; - kroundup32(s->m); - s->s = (char*)realloc(s->s, s->m); - } - memcpy(s->s + s->l, p, l); - s->l += l; - s->s[s->l] = 0; - return l; -} - -s3aux_t s3_parse(const char *url, const char *_id, const char *_secret, const char *fn_secret) -{ - const char *id, *secret, *bucket, *obj; - char *id_secret = 0, date[64], sig[29]; - time_t t; - struct tm tmt; - s3aux_t a = {0,0}; - kstring_t str = {0,0,0}; - // parse URL - if (strstr(url, "s3://") != url) return a; - bucket = url + 5; - for (obj = bucket; *obj && *obj != '/'; ++obj); - if (*obj == 0) return a; // no object - // acquire AWS credential and time - if (_id == 0 || _secret == 0) { - id_secret = s3_read_awssecret(fn_secret); - if (id_secret == 0) return a; // fail to read the AWS credential - id = id_secret; - secret = id_secret + strlen(id) + 1; - } else id = _id, secret = _secret; - // compose URL for curl - kputsn("https://", 8, &str); - kputsn(bucket, obj - bucket, &str); - kputsn(".s3.amazonaws.com", 17, &str); - kputsn(obj, strlen(obj), &str); - a.url = str.s; - // compose the Date line - str.l = str.m = 0; str.s = 0; - t = time(0); - strftime(date, 64, "%a, %d %b %Y %H:%M:%S +0000", gmtime_r(&t, &tmt)); - kputsn("Date: ", 6, &str); - kputsn(date, strlen(date), &str); - a.date = str.s; - // compose the string to sign and sign it - str.l = str.m = 0; str.s = 0; - kputsn("GET\n\n\n", 6, &str); - kputsn(date, strlen(date), &str); - kputsn("\n", 1, &str); - kputsn(bucket-1, strlen(bucket-1), &str); - s3_sign(secret, str.s, sig); - // compose the Authorization line - str.l = 0; - kputsn("Authorization: AWS ", 19, &str); - kputsn(id, strlen(id), &str); - kputsn(":", 1, &str); - kputsn(sig, strlen(sig), &str); - a.auth = str.s; -// printf("curl -H '%s' -H '%s' %s\n", a.date, a.auth, a.url); - return a; -} - -/********************* - *** Main function *** - *********************/ - -#ifdef KURL_MAIN -int main(int argc, char *argv[]) -{ - kurl_t *f; - int c, l, l_buf = 0x10000; - off_t start = 0, rest = -1; - uint8_t *buf; - char *p; - kurl_opt_t opt; - - memset(&opt, 0, sizeof(kurl_opt_t)); - while ((c = getopt(argc, argv, "c:l:a:")) >= 0) { - if (c == 'c') start = strtol(optarg, &p, 0); - else if (c == 'l') rest = strtol(optarg, &p, 0); - else if (c == 'a') opt.s3key_fn = optarg; - } - if (optind == argc) { - fprintf(stderr, "Usage: kurl [-c start] [-l length] <url>\n"); - return 1; - } - kurl_init(); - f = kurl_open(argv[optind], &opt); - if (f == 0) { - fprintf(stderr, "ERROR: fail to open URL\n"); - return 2; - } - if (start > 0) { - if (kurl_seek(f, start, SEEK_SET) < 0) { - kurl_close(f); - fprintf(stderr, "ERROR: fail to seek\n"); - return 3; - } - } - buf = (uint8_t*)calloc(l_buf, 1); - while (rest != 0) { - int to_read = rest > 0 && rest < l_buf? rest : l_buf; - l = kurl_read(f, buf, to_read); - if (l == 0) break; - fwrite(buf, 1, l, stdout); - rest -= l; - } - free(buf); - kurl_close(f); - kurl_destroy(); - return 0; -} -#endif diff --git a/web/server/h2o/libh2o/deps/klib/kurl.h b/web/server/h2o/libh2o/deps/klib/kurl.h deleted file mode 100644 index f07f64118..000000000 --- a/web/server/h2o/libh2o/deps/klib/kurl.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef KURL_H -#define KURL_H - -#include <sys/types.h> - -#define KURL_NULL 1 -#define KURL_INV_WHENCE 2 -#define KURL_SEEK_OUT 3 -#define KURL_NO_AUTH 4 - -struct kurl_t; -typedef struct kurl_t kurl_t; - -typedef struct { - const char *s3keyid; - const char *s3secretkey; - const char *s3key_fn; -} kurl_opt_t; - -#ifdef __cplusplus -extern "C" { -#endif - -int kurl_init(void); -void kurl_destroy(void); - -kurl_t *kurl_open(const char *url, kurl_opt_t *opt); -kurl_t *kurl_dopen(int fd); -int kurl_close(kurl_t *ku); -ssize_t kurl_read(kurl_t *ku, void *buf, size_t nbytes); -off_t kurl_seek(kurl_t *ku, off_t offset, int whence); -int kurl_buflen(kurl_t *ku, int len); - -off_t kurl_tell(const kurl_t *ku); -int kurl_eof(const kurl_t *ku); -int kurl_fileno(const kurl_t *ku); -int kurl_error(const kurl_t *ku); - -#ifdef __cplusplus -} -#endif - -#ifndef KNETFILE_H -#define KNETFILE_H -typedef kurl_t knetFile; -#define knet_open(fn, mode) kurl_open(fn, 0) -#define knet_dopen(fd, mode) kurl_dopen(fd) -#define knet_close(fp) kurl_close(fp) -#define knet_read(fp, buf, len) kurl_read(fp, buf, len) -#define knet_seek(fp, off, whence) kurl_seek(fp, off, whence) -#define knet_tell(fp) kurl_tell(fp) -#define knet_fileno(fp) kurl_fileno(fp) -#define knet_win32_init() kurl_init() -#define knet_win32_destroy() kurl_destroy() -#endif - -#endif diff --git a/web/server/h2o/libh2o/deps/klib/kvec.h b/web/server/h2o/libh2o/deps/klib/kvec.h deleted file mode 100644 index 676be8b80..000000000 --- a/web/server/h2o/libh2o/deps/klib/kvec.h +++ /dev/null @@ -1,90 +0,0 @@ -/* The MIT License - - Copyright (c) 2008, by Attractive Chaos <attractor@live.co.uk> - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. -*/ - -/* - An example: - -#include "kvec.h" -int main() { - kvec_t(int) array; - kv_init(array); - kv_push(int, array, 10); // append - kv_a(int, array, 20) = 5; // dynamic - kv_A(array, 20) = 4; // static - kv_destroy(array); - return 0; -} -*/ - -/* - 2008-09-22 (0.1.0): - - * The initial version. - -*/ - -#ifndef AC_KVEC_H -#define AC_KVEC_H - -#include <stdlib.h> - -#define kv_roundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) - -#define kvec_t(type) struct { size_t n, m; type *a; } -#define kv_init(v) ((v).n = (v).m = 0, (v).a = 0) -#define kv_destroy(v) free((v).a) -#define kv_A(v, i) ((v).a[(i)]) -#define kv_pop(v) ((v).a[--(v).n]) -#define kv_size(v) ((v).n) -#define kv_max(v) ((v).m) - -#define kv_resize(type, v, s) ((v).m = (s), (v).a = (type*)realloc((v).a, sizeof(type) * (v).m)) - -#define kv_copy(type, v1, v0) do { \ - if ((v1).m < (v0).n) kv_resize(type, v1, (v0).n); \ - (v1).n = (v0).n; \ - memcpy((v1).a, (v0).a, sizeof(type) * (v0).n); \ - } while (0) \ - -#define kv_push(type, v, x) do { \ - if ((v).n == (v).m) { \ - (v).m = (v).m? (v).m<<1 : 2; \ - (v).a = (type*)realloc((v).a, sizeof(type) * (v).m); \ - } \ - (v).a[(v).n++] = (x); \ - } while (0) - -#define kv_pushp(type, v) (((v).n == (v).m)? \ - ((v).m = ((v).m? (v).m<<1 : 2), \ - (v).a = (type*)realloc((v).a, sizeof(type) * (v).m), 0) \ - : 0), ((v).a + ((v).n++)) - -#define kv_a(type, v, i) (((v).m <= (size_t)(i)? \ - ((v).m = (v).n = (i) + 1, kv_roundup32((v).m), \ - (v).a = (type*)realloc((v).a, sizeof(type) * (v).m), 0) \ - : (v).n <= (size_t)(i)? (v).n = (i) + 1 \ - : 0), (v).a[(i)]) - -#endif diff --git a/web/server/h2o/libh2o/deps/klib/lua/bio.lua b/web/server/h2o/libh2o/deps/klib/lua/bio.lua deleted file mode 100644 index c9f220059..000000000 --- a/web/server/h2o/libh2o/deps/klib/lua/bio.lua +++ /dev/null @@ -1,149 +0,0 @@ --- bioinformatics routines - --- Description: read a fasta/fastq file -local function readseq(fp) - local finished, last = false, nil; - return function() - local match; - if finished then return nil end - if (last == nil) then -- the first record or a record following a fastq - for l in fp:lines() do - if l:byte(1) == 62 or l:byte(1) == 64 then -- ">" || "@" - last = l; - break; - end - end - if last == nil then - finished = true; - return nil; - end - end - local tmp = last:find("%s"); - name = (tmp and last:sub(2, tmp-1)) or last:sub(2); -- sequence name - local seqs = {}; - local c; -- the first character of the last line - last = nil; - for l in fp:lines() do -- read sequence - c = l:byte(1); - if c == 62 or c == 64 or c == 43 then - last = l; - break; - end - table.insert(seqs, l); - end - if last == nil then finished = true end -- end of file - if c ~= 43 then return name, table.concat(seqs) end -- a fasta record - local seq, len = table.concat(seqs), 0; -- prepare to parse quality - seqs = {}; - for l in fp:lines() do -- read quality - table.insert(seqs, l); - len = len + #l; - if len >= #seq then - last = nil; - return name, seq, table.concat(seqs); - end - end - finished = true; - return name, seq; - end -end - --- extract subsequence from a fasta file indexe by samtools faidx -local function faidxsub(fn) - local fpidx = io.open(fn .. ".fai"); - if fpidx == nil then - io.stderr:write("[faidxsub] fail to open the FASTA index file.\n"); - return nil - end - local idx = {}; - for l in fpidx:lines() do - local name, len, offset, line_blen, line_len = l:match("(%S+)%s(%d+)%s(%d+)%s(%d+)%s(%d+)"); - if name then - idx[name] = {tonumber(len), offset, line_blen, line_len}; - end - end - fpidx:close(); - local fp = io.open(fn); - return function(name, beg_, end_) -- 0-based coordinate - if name == nil then fp:close(); return nil; end - if idx[name] then - local a = idx[name]; - beg_ = beg_ or 0; - end_ = end_ or a[1]; - end_ = (end_ <= a[1] and end_) or a[1]; - local fb, fe = math.floor(beg_ / a[3]), math.floor(end_ / a[3]); - local qb, qe = beg_ - fb * a[3], end_ - fe * a[3]; - fp:seek("set", a[2] + fb * a[4] + qb); - local s = fp:read((fe - fb) * a[4] + (qe - qb)):gsub("%s", ""); - return s; - end - end -end - ---Description: Index a list of intervals and test if a given interval overlaps with the list ---Example: lua -lbio -e 'a={{100,201},{200,300},{400,600}};f=bio.intvovlp(a);print(f(600,700))' ---[[ - By default, we keep for each tiling 8192 window the interval overlaping the - window while having the smallest start position. This method may not work - well when most intervals are small but few intervals span a long distance. -]]-- -local function intvovlp(intv, bits) - bits = bits or 13 -- the default bin size is 8192 = 1<<13 - table.sort(intv, function(a,b) return a[1] < b[1] end) -- sort by the start - -- merge intervals; the step speeds up testing, but can be skipped - local b, e, k = -1, -1, 1 - for i = 1, #intv do - if e < intv[i][1] then - if e >= 0 then intv[k], k = {b, e}, k + 1 end - b, e = intv[i][1], intv[i][2] - else e = intv[i][2] end - end - if e >= 0 then intv[k] = {b, e} end - while #a > k do table.remove(a) end -- truncate the interval list - -- build the index for the list of intervals - local idx, size, max = {}, math.pow(2, bits), 0 - for i = 1, #a do - b = math.modf(intv[i][1] / size) - e = math.modf(intv[i][2] / size) - if b == e then idx[b] = idx[b] or i - else for j = b, e do idx[j] = idx[j] or i end end - max = (max > e and max) or e - end - -- return a function (closure) - return function(_beg, _end) - local x = math.modf(_beg / size) - if x > max then return false end - local off = idx[x]; -- the start bin - if off == nil then -- the following is not the best in efficiency - for i = x - 1, 0, -1 do -- find the minimum bin with a value - if idx[i] ~= nil then off = idx[i]; break; end - end - if off == nil then return false end - end - for i = off, #intv do -- start from off and search for overlaps - if intv[i][1] >= _end then return false - elseif intv[i][2] > _beg then return true end - end - return false - end -end - -bio = { - readseq = readseq, - faidxsub = faidxsub, - intvovlp = intvovlp -} - -bio.nt16 = { -[0]=15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, - 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, - 15, 1,14, 2, 13,15,15, 4, 11,15,15,12, 15, 3,15,15, 15,15, 5, 6, 8,15, 7, 9, 0,10,15,15, 15,15,15,15, - 15, 1,14, 2, 13,15,15, 4, 11,15,15,12, 15, 3,15,15, 15,15, 5, 6, 8,15, 7, 9, 0,10,15,15, 15,15,15,15, - 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, - 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, - 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, - 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15 -} -bio.ntcnt = { [0]=4, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 } -bio.ntcomp = { [0]=0, 8, 4, 12, 2, 10, 9, 14, 1, 6, 5, 13, 3, 11, 7, 15 } -bio.ntrev = 'XACMGRSVTWYHKDBN' diff --git a/web/server/h2o/libh2o/deps/klib/lua/klib.lua b/web/server/h2o/libh2o/deps/klib/lua/klib.lua deleted file mode 100644 index bfe52f7f7..000000000 --- a/web/server/h2o/libh2o/deps/klib/lua/klib.lua +++ /dev/null @@ -1,677 +0,0 @@ ---[[ - The MIT License - - Copyright (c) 2011, Attractive Chaos <attractor@live.co.uk> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. -]]-- - ---[[ - This is a Lua library, more exactly a collection of Lua snippets, covering - utilities (e.g. getopt), string operations (e.g. split), statistics (e.g. - Fisher's exact test), special functions (e.g. logarithm gamma) and matrix - operations (e.g. Gauss-Jordan elimination). The routines are designed to be - as independent as possible, such that one can copy-paste relevant pieces of - code without worrying about additional library dependencies. - - If you use routines from this library, please include the licensing - information above where appropriate. -]]-- - ---[[ - Library functions and dependencies. "a>b" means "a is required by b"; "b<a" - means "b depends on a". - - os.getopt() - string:split() - io.xopen() - table.ksmall() - table.shuffle() - math.lgamma() >math.lbinom() >math.igamma() - math.igamma() <math.lgamma() >matrix.chi2() - math.erfc() - math.lbinom() <math.lgamma() >math.fisher_exact() - math.bernstein_poly() <math.lbinom() - math.fisher_exact() <math.lbinom() - math.jackknife() - math.pearson() - math.spearman() - math.fmin() - matrix - matrix.add() - matrix.T() >matrix.mul() - matrix.mul() <matrix.T() - matrix.tostring() - matrix.chi2() <math.igamma() - matrix.solve() -]]-- - --- Description: getopt() translated from the BSD getopt(); compatible with the default Unix getopt() ---[[ Example: - for o, a in os.getopt(arg, 'a:b') do - print(o, a) - end -]]-- -function os.getopt(args, ostr) - local arg, place = nil, 0; - return function () - if place == 0 then -- update scanning pointer - place = 1 - if #args == 0 or args[1]:sub(1, 1) ~= '-' then place = 0; return nil end - if #args[1] >= 2 then - place = place + 1 - if args[1]:sub(2, 2) == '-' then -- found "--" - place = 0 - table.remove(args, 1); - return nil; - end - end - end - local optopt = args[1]:sub(place, place); - place = place + 1; - local oli = ostr:find(optopt); - if optopt == ':' or oli == nil then -- unknown option - if optopt == '-' then return nil end - if place > #args[1] then - table.remove(args, 1); - place = 0; - end - return '?'; - end - oli = oli + 1; - if ostr:sub(oli, oli) ~= ':' then -- do not need argument - arg = nil; - if place > #args[1] then - table.remove(args, 1); - place = 0; - end - else -- need an argument - if place <= #args[1] then -- no white space - arg = args[1]:sub(place); - else - table.remove(args, 1); - if #args == 0 then -- an option requiring argument is the last one - place = 0; - if ostr:sub(1, 1) == ':' then return ':' end - return '?'; - else arg = args[1] end - end - table.remove(args, 1); - place = 0; - end - return optopt, arg; - end -end - --- Description: string split -function string:split(sep, n) - local a, start = {}, 1; - sep = sep or "%s+"; - repeat - local b, e = self:find(sep, start); - if b == nil then - table.insert(a, self:sub(start)); - break - end - a[#a+1] = self:sub(start, b - 1); - start = e + 1; - if n and #a == n then - table.insert(a, self:sub(start)); - break - end - until start > #self; - return a; -end - --- Description: smart file open -function io.xopen(fn, mode) - mode = mode or 'r'; - if fn == nil then return io.stdin; - elseif fn == '-' then return (mode == 'r' and io.stdin) or io.stdout; - elseif fn:sub(-3) == '.gz' then return (mode == 'r' and io.popen('gzip -dc ' .. fn, 'r')) or io.popen('gzip > ' .. fn, 'w'); - elseif fn:sub(-4) == '.bz2' then return (mode == 'r' and io.popen('bzip2 -dc ' .. fn, 'r')) or io.popen('bgzip2 > ' .. fn, 'w'); - else return io.open(fn, mode) end -end - --- Description: find the k-th smallest element in an array (Ref. http://ndevilla.free.fr/median/) -function table.ksmall(arr, k) - local low, high = 1, #arr; - while true do - if high <= low then return arr[k] end - if high == low + 1 then - if arr[high] < arr[low] then arr[high], arr[low] = arr[low], arr[high] end; - return arr[k]; - end - local mid = math.floor((high + low) / 2); - if arr[high] < arr[mid] then arr[mid], arr[high] = arr[high], arr[mid] end - if arr[high] < arr[low] then arr[low], arr[high] = arr[high], arr[low] end - if arr[low] < arr[mid] then arr[low], arr[mid] = arr[mid], arr[low] end - arr[mid], arr[low+1] = arr[low+1], arr[mid]; - local ll, hh = low + 1, high; - while true do - repeat ll = ll + 1 until arr[ll] >= arr[low] - repeat hh = hh - 1 until arr[low] >= arr[hh] - if hh < ll then break end - arr[ll], arr[hh] = arr[hh], arr[ll]; - end - arr[low], arr[hh] = arr[hh], arr[low]; - if hh <= k then low = ll end - if hh >= k then high = hh - 1 end - end -end - --- Description: shuffle/permutate an array -function table.shuffle(a) - for i = #a, 1, -1 do - local j = math.random(i) - a[j], a[i] = a[i], a[j] - end -end - --- --- Mathematics --- - --- Description: log gamma function --- Required by: math.lbinom() --- Reference: AS245, 2nd algorithm, http://lib.stat.cmu.edu/apstat/245 -function math.lgamma(z) - local x; - x = 0.1659470187408462e-06 / (z+7); - x = x + 0.9934937113930748e-05 / (z+6); - x = x - 0.1385710331296526 / (z+5); - x = x + 12.50734324009056 / (z+4); - x = x - 176.6150291498386 / (z+3); - x = x + 771.3234287757674 / (z+2); - x = x - 1259.139216722289 / (z+1); - x = x + 676.5203681218835 / z; - x = x + 0.9999999999995183; - return math.log(x) - 5.58106146679532777 - z + (z-0.5) * math.log(z+6.5); -end - --- Description: regularized incomplete gamma function --- Dependent on: math.lgamma() ---[[ - Formulas are taken from Wiki, with additional input from Numerical - Recipes in C (for modified Lentz's algorithm) and AS245 - (http://lib.stat.cmu.edu/apstat/245). - - A good online calculator is available at: - - http://www.danielsoper.com/statcalc/calc23.aspx - - It calculates upper incomplete gamma function, which equals - math.igamma(s,z,true)*math.exp(math.lgamma(s)) -]]-- -function math.igamma(s, z, complement) - - local function _kf_gammap(s, z) - local sum, x = 1, 1; - for k = 1, 100 do - x = x * z / (s + k); - sum = sum + x; - if x / sum < 1e-14 then break end - end - return math.exp(s * math.log(z) - z - math.lgamma(s + 1.) + math.log(sum)); - end - - local function _kf_gammaq(s, z) - local C, D, f, TINY; - f = 1. + z - s; C = f; D = 0.; TINY = 1e-290; - -- Modified Lentz's algorithm for computing continued fraction. See Numerical Recipes in C, 2nd edition, section 5.2 - for j = 1, 100 do - local d; - local a, b = j * (s - j), j*2 + 1 + z - s; - D = b + a * D; - if D < TINY then D = TINY end - C = b + a / C; - if C < TINY then C = TINY end - D = 1. / D; - d = C * D; - f = f * d; - if math.abs(d - 1) < 1e-14 then break end - end - return math.exp(s * math.log(z) - z - math.lgamma(s) - math.log(f)); - end - - if complement then - return ((z <= 1 or z < s) and 1 - _kf_gammap(s, z)) or _kf_gammaq(s, z); - else - return ((z <= 1 or z < s) and _kf_gammap(s, z)) or (1 - _kf_gammaq(s, z)); - end -end - -math.M_SQRT2 = 1.41421356237309504880 -- sqrt(2) -math.M_SQRT1_2 = 0.70710678118654752440 -- 1/sqrt(2) - --- Description: complement error function erfc(x): \Phi(x) = 0.5 * erfc(-x/M_SQRT2) -function math.erfc(x) - local z = math.abs(x) * math.M_SQRT2 - if z > 37 then return (x > 0 and 0) or 2 end - local expntl = math.exp(-0.5 * z * z) - local p - if z < 10. / math.M_SQRT2 then -- for small z - p = expntl * ((((((.03526249659989109 * z + .7003830644436881) * z + 6.37396220353165) * z + 33.912866078383) - * z + 112.0792914978709) * z + 221.2135961699311) * z + 220.2068679123761) - / (((((((.08838834764831844 * z + 1.755667163182642) * z + 16.06417757920695) * z + 86.78073220294608) - * z + 296.5642487796737) * z + 637.3336333788311) * z + 793.8265125199484) * z + 440.4137358247522); - else p = expntl / 2.506628274631001 / (z + 1. / (z + 2. / (z + 3. / (z + 4. / (z + .65))))) end - return (x > 0 and 2 * p) or 2 * (1 - p) -end - --- Description: log binomial coefficient --- Dependent on: math.lgamma() --- Required by: math.fisher_exact() -function math.lbinom(n, m) - if m == nil then - local a = {}; - a[0], a[n] = 0, 0; - local t = math.lgamma(n+1); - for m = 1, n-1 do a[m] = t - math.lgamma(m+1) - math.lgamma(n-m+1) end - return a; - else return math.lgamma(n+1) - math.lgamma(m+1) - math.lgamma(n-m+1) end -end - --- Description: Berstein polynomials (mainly for Bezier curves) --- Dependent on: math.lbinom() --- Note: to compute derivative: let beta_new[i]=beta[i+1]-beta[i] -function math.bernstein_poly(beta) - local n = #beta - 1; - local lbc = math.lbinom(n); -- log binomial coefficients - return function (t) - assert(t >= 0 and t <= 1); - if t == 0 then return beta[1] end - if t == 1 then return beta[n+1] end - local sum, logt, logt1 = 0, math.log(t), math.log(1-t); - for i = 0, n do sum = sum + beta[i+1] * math.exp(lbc[i] + i * logt + (n-i) * logt1) end - return sum; - end -end - --- Description: Fisher's exact test --- Dependent on: math.lbinom() --- Return: left-, right- and two-tail P-values ---[[ - Fisher's exact test for 2x2 congintency tables: - - n11 n12 | n1_ - n21 n22 | n2_ - -----------+---- - n_1 n_2 | n - - Reference: http://www.langsrud.com/fisher.htm -]]-- -function math.fisher_exact(n11, n12, n21, n22) - local aux; -- keep the states of n* for acceleration - - -- Description: hypergeometric function - local function hypergeo(n11, n1_, n_1, n) - return math.exp(math.lbinom(n1_, n11) + math.lbinom(n-n1_, n_1-n11) - math.lbinom(n, n_1)); - end - - -- Description: incremental hypergeometric function - -- Note: aux = {n11, n1_, n_1, n, p} - local function hypergeo_inc(n11, n1_, n_1, n) - if n1_ ~= 0 or n_1 ~= 0 or n ~= 0 then - aux = {n11, n1_, n_1, n, 1}; - else -- then only n11 is changed - local mod; - _, mod = math.modf(n11 / 11); - if mod ~= 0 and n11 + aux[4] - aux[2] - aux[3] ~= 0 then - if n11 == aux[1] + 1 then -- increase by 1 - aux[5] = aux[5] * (aux[2] - aux[1]) / n11 * (aux[3] - aux[1]) / (n11 + aux[4] - aux[2] - aux[3]); - aux[1] = n11; - return aux[5]; - end - if n11 == aux[1] - 1 then -- descrease by 1 - aux[5] = aux[5] * aux[1] / (aux[2] - n11) * (aux[1] + aux[4] - aux[2] - aux[3]) / (aux[3] - n11); - aux[1] = n11; - return aux[5]; - end - end - aux[1] = n11; - end - aux[5] = hypergeo(aux[1], aux[2], aux[3], aux[4]); - return aux[5]; - end - - -- Description: computing the P-value by Fisher's exact test - local max, min, left, right, n1_, n_1, n, two, p, q, i, j; - n1_, n_1, n = n11 + n12, n11 + n21, n11 + n12 + n21 + n22; - max = (n_1 < n1_ and n_1) or n1_; -- max n11, for the right tail - min = n1_ + n_1 - n; - if min < 0 then min = 0 end -- min n11, for the left tail - two, left, right = 1, 1, 1; - if min == max then return 1 end -- no need to do test - q = hypergeo_inc(n11, n1_, n_1, n); -- the probability of the current table - -- left tail - i, left, p = min + 1, 0, hypergeo_inc(min, 0, 0, 0); - while p < 0.99999999 * q do - left, p, i = left + p, hypergeo_inc(i, 0, 0, 0), i + 1; - end - i = i - 1; - if p < 1.00000001 * q then left = left + p; - else i = i - 1 end - -- right tail - j, right, p = max - 1, 0, hypergeo_inc(max, 0, 0, 0); - while p < 0.99999999 * q do - right, p, j = right + p, hypergeo_inc(j, 0, 0, 0), j - 1; - end - j = j + 1; - if p < 1.00000001 * q then right = right + p; - else j = j + 1 end - -- two-tail - two = left + right; - if two > 1 then two = 1 end - -- adjust left and right - if math.abs(i - n11) < math.abs(j - n11) then right = 1 - left + q; - else left = 1 - right + q end - return left, right, two; -end - --- Description: Delete-m Jackknife ---[[ - Given g groups of values with a statistics estimated from m[i] samples in - i-th group being t[i], compute the mean and the variance. t0 below is the - estimate from all samples. Reference: - - Busing et al. (1999) Delete-m Jackknife for unequal m. Statistics and Computing, 9:3-8. -]]-- -function math.jackknife(g, m, t, t0) - local h, n, sum = {}, 0, 0; - for j = 1, g do n = n + m[j] end - if t0 == nil then -- When t0 is absent, estimate it in a naive way - t0 = 0; - for j = 1, g do t0 = t0 + m[j] * t[j] end - t0 = t0 / n; - end - local mean, var = 0, 0; - for j = 1, g do - h[j] = n / m[j]; - mean = mean + (1 - m[j] / n) * t[j]; - end - mean = g * t0 - mean; -- Eq. (8) - for j = 1, g do - local x = h[j] * t0 - (h[j] - 1) * t[j] - mean; - var = var + 1 / (h[j] - 1) * x * x; - end - var = var / g; - return mean, var; -end - --- Description: Pearson correlation coefficient --- Input: a is an n*2 table -function math.pearson(a) - -- compute the mean - local x1, y1 = 0, 0 - for _, v in pairs(a) do - x1, y1 = x1 + v[1], y1 + v[2] - end - -- compute the coefficient - x1, y1 = x1 / #a, y1 / #a - local x2, y2, xy = 0, 0, 0 - for _, v in pairs(a) do - local tx, ty = v[1] - x1, v[2] - y1 - xy, x2, y2 = xy + tx * ty, x2 + tx * tx, y2 + ty * ty - end - return xy / math.sqrt(x2) / math.sqrt(y2) -end - --- Description: Spearman correlation coefficient -function math.spearman(a) - local function aux_func(t) -- auxiliary function - return (t == 1 and 0) or (t*t - 1) * t / 12 - end - - for _, v in pairs(a) do v.r = {} end - local T, S = {}, {} - -- compute the rank - for k = 1, 2 do - table.sort(a, function(u,v) return u[k]<v[k] end) - local same = 1 - T[k] = 0 - for i = 2, #a + 1 do - if i <= #a and a[i-1][k] == a[i][k] then same = same + 1 - else - local rank = (i-1) * 2 - same + 1 - for j = i - same, i - 1 do a[j].r[k] = rank end - if same > 1 then T[k], same = T[k] + aux_func(same), 1 end - end - end - S[k] = aux_func(#a) - T[k] - end - -- compute the coefficient - local sum = 0 - for _, v in pairs(a) do -- TODO: use nested loops to reduce loss of precision - local t = (v.r[1] - v.r[2]) / 2 - sum = sum + t * t - end - return (S[1] + S[2] - sum) / 2 / math.sqrt(S[1] * S[2]) -end - --- Description: Hooke-Jeeves derivative-free optimization -function math.fmin(func, x, data, r, eps, max_calls) - local n, n_calls = #x, 0; - r = r or 0.5; - eps = eps or 1e-7; - max_calls = max_calls or 50000 - - function fmin_aux(x1, data, fx1, dx) -- auxiliary function - local ftmp; - for k = 1, n do - x1[k] = x1[k] + dx[k]; - local ftmp = func(x1, data); n_calls = n_calls + 1; - if ftmp < fx1 then fx1 = ftmp; - else -- search the opposite direction - dx[k] = -dx[k]; - x1[k] = x1[k] + dx[k] + dx[k]; - ftmp = func(x1, data); n_calls = n_calls + 1; - if ftmp < fx1 then fx1 = ftmp - else x1[k] = x1[k] - dx[k] end -- back to the original x[k] - end - end - return fx1; -- here: fx1=f(n,x1) - end - - local dx, x1 = {}, {}; - for k = 1, n do -- initial directions, based on MGJ - dx[k] = math.abs(x[k]) * r; - if dx[k] == 0 then dx[k] = r end; - end - local radius = r; - local fx1, fx; - fx = func(x, data); fx1 = fx; n_calls = n_calls + 1; - while true do - for i = 1, n do x1[i] = x[i] end; -- x1 = x - fx1 = fmin_aux(x1, data, fx, dx); - while fx1 < fx do - for k = 1, n do - local t = x[k]; - dx[k] = (x1[k] > x[k] and math.abs(dx[k])) or -math.abs(dx[k]); - x[k] = x1[k]; - x1[k] = x1[k] + x1[k] - t; - end - fx = fx1; - if n_calls >= max_calls then break end - fx1 = func(x1, data); n_calls = n_calls + 1; - fx1 = fmin_aux(x1, data, fx1, dx); - if fx1 >= fx then break end - local kk = n; - for k = 1, n do - if math.abs(x1[k] - x[k]) > .5 * math.abs(dx[k]) then - kk = k; - break; - end - end - if kk == n then break end - end - if radius >= eps then - if n_calls >= max_calls then break end - radius = radius * r; - for k = 1, n do dx[k] = dx[k] * r end - else break end - end - return fx1, n_calls; -end - --- --- Matrix --- - -matrix = {} - --- Description: matrix transpose --- Required by: matrix.mul() -function matrix.T(a) - local m, n, x = #a, #a[1], {}; - for i = 1, n do - x[i] = {}; - for j = 1, m do x[i][j] = a[j][i] end - end - return x; -end - --- Description: matrix add -function matrix.add(a, b) - assert(#a == #b and #a[1] == #b[1]); - local m, n, x = #a, #a[1], {}; - for i = 1, m do - x[i] = {}; - local ai, bi, xi = a[i], b[i], x[i]; - for j = 1, n do xi[j] = ai[j] + bi[j] end - end - return x; -end - --- Description: matrix mul --- Dependent on: matrix.T() --- Note: much slower without transpose -function matrix.mul(a, b) - assert(#a[1] == #b); - local m, n, p, x = #a, #a[1], #b[1], {}; - local c = matrix.T(b); -- transpose for efficiency - for i = 1, m do - x[i] = {} - local xi = x[i]; - for j = 1, p do - local sum, ai, cj = 0, a[i], c[j]; - for k = 1, n do sum = sum + ai[k] * cj[k] end - xi[j] = sum; - end - end - return x; -end - --- Description: matrix print -function matrix.tostring(a) - local z = {}; - for i = 1, #a do - z[i] = table.concat(a[i], "\t"); - end - return table.concat(z, "\n"); -end - --- Description: chi^2 test for contingency tables --- Dependent on: math.igamma() -function matrix.chi2(a) - if #a == 2 and #a[1] == 2 then -- 2x2 table - local x, z - x = (a[1][1] + a[1][2]) * (a[2][1] + a[2][2]) * (a[1][1] + a[2][1]) * (a[1][2] + a[2][2]) - if x == 0 then return 0, 1, false end - z = a[1][1] * a[2][2] - a[1][2] * a[2][1] - z = (a[1][1] + a[1][2] + a[2][1] + a[2][2]) * z * z / x - return z, math.igamma(.5, .5 * z, true), true - else -- generic table - local rs, cs, n, m, N, z = {}, {}, #a, #a[1], 0, 0 - for i = 1, n do rs[i] = 0 end - for j = 1, m do cs[j] = 0 end - for i = 1, n do -- compute column sum and row sum - for j = 1, m do cs[j], rs[i] = cs[j] + a[i][j], rs[i] + a[i][j] end - end - for i = 1, n do N = N + rs[i] end - for i = 1, n do -- compute the chi^2 statistics - for j = 1, m do - local E = rs[i] * cs[j] / N; - z = z + (a[i][j] - E) * (a[i][j] - E) / E - end - end - return z, math.igamma(.5 * (n-1) * (m-1), .5 * z, true), true; - end -end - --- Description: Gauss-Jordan elimination (solving equations; computing inverse) --- Note: on return, a[n][n] is the inverse; b[n][m] is the solution --- Reference: Section 2.1, Numerical Recipes in C, 2nd edition -function matrix.solve(a, b) - assert(#a == #a[1]); - local n, m = #a, (b and #b[1]) or 0; - local xc, xr, ipiv = {}, {}, {}; - local ic, ir; - - for j = 1, n do ipiv[j] = 0 end - for i = 1, n do - local big = 0; - for j = 1, n do - local aj = a[j]; - if ipiv[j] ~= 1 then - for k = 1, n do - if ipiv[k] == 0 then - if math.abs(aj[k]) >= big then - big = math.abs(aj[k]); - ir, ic = j, k; - end - elseif ipiv[k] > 1 then return -2 end -- singular matrix - end - end - end - ipiv[ic] = ipiv[ic] + 1; - if ir ~= ic then - for l = 1, n do a[ir][l], a[ic][l] = a[ic][l], a[ir][l] end - if b then - for l = 1, m do b[ir][l], b[ic][l] = b[ic][l], b[ir][l] end - end - end - xr[i], xc[i] = ir, ic; - if a[ic][ic] == 0 then return -3 end -- singular matrix - local pivinv = 1 / a[ic][ic]; - a[ic][ic] = 1; - for l = 1, n do a[ic][l] = a[ic][l] * pivinv end - if b then - for l = 1, n do b[ic][l] = b[ic][l] * pivinv end - end - for ll = 1, n do - if ll ~= ic then - local tmp = a[ll][ic]; - a[ll][ic] = 0; - local all, aic = a[ll], a[ic]; - for l = 1, n do all[l] = all[l] - aic[l] * tmp end - if b then - local bll, bic = b[ll], b[ic]; - for l = 1, m do bll[l] = bll[l] - bic[l] * tmp end - end - end - end - end - for l = n, 1, -1 do - if xr[l] ~= xc[l] then - for k = 1, n do a[k][xr[l]], a[k][xc[l]] = a[k][xc[l]], a[k][xr[l]] end - end - end - return 0; -end diff --git a/web/server/h2o/libh2o/deps/klib/test/Makefile b/web/server/h2o/libh2o/deps/klib/test/Makefile deleted file mode 100644 index a392c8ed4..000000000 --- a/web/server/h2o/libh2o/deps/klib/test/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -CC=gcc -CXX=g++ -CFLAGS=-g -Wall -O2 -I.. -CXXFLAGS=$(CFLAGS) -PROGS=kbtree_test khash_keith khash_keith2 khash_test klist_test kseq_test kseq_bench \ - kseq_bench2 ksort_test ksort_test-stl kvec_test kmin_test kstring_bench kstring_bench2 kstring_test \ - kthread_test - -all:$(PROGS) - -clean: - rm -fr $(PROGS) *.dSYM a.out - -kbtree_test:kbtree_test.c ../kbtree.h - $(CC) $(CFLAGS) -o $@ kbtree_test.c - -khash_keith:khash_keith.c ../khash.h - $(CC) $(CFLAGS) -o $@ khash_keith.c - -khash_keith2:khash_keith2.c ../khash.h - $(CC) $(CFLAGS) -o $@ khash_keith2.c - -khash_test:khash_test.c ../khash.h - $(CC) $(CFLAGS) -o $@ khash_test.c - -klist_test:klist_test.c ../klist.h - $(CC) $(CFLAGS) -o $@ klist_test.c - -kseq_test:kseq_test.c ../kseq.h - $(CC) $(CFLAGS) -o $@ kseq_test.c -lz - -kseq_bench:kseq_bench.c ../kseq.h - $(CC) $(CFLAGS) -o $@ kseq_bench.c -lz - -kseq_bench2:kseq_bench2.c ../kseq.h - $(CC) $(CFLAGS) -o $@ kseq_bench2.c -lz - -ksort_test:ksort_test.c ../ksort.h - $(CC) $(CFLAGS) -o $@ ksort_test.c - -ksort_test-stl:ksort_test.cc ../ksort.h - $(CXX) $(CXXFLAGS) -o $@ ksort_test.cc - -kvec_test:kvec_test.cc ../kvec.h - $(CXX) $(CXXFLAGS) -o $@ kvec_test.cc - -kmin_test:kmin_test.c ../kmath.h ../kmath.c - $(CC) $(CFLAGS) -o $@ kmin_test.c ../kmath.c - -kstring_bench:kstring_bench.c ../kstring.h ../kstring.c - $(CC) $(CFLAGS) -o $@ kstring_bench.c ../kstring.c - -kstring_bench2:kstring_bench2.c ../kstring.h ../kstring.c - $(CC) $(CFLAGS) -o $@ kstring_bench2.c ../kstring.c - -kstring_test:kstring_test.c ../kstring.h ../kstring.c - $(CC) $(CFLAGS) -o $@ kstring_test.c ../kstring.c - -kthread_test:kthread_test.c ../kthread.c - $(CC) $(CFLAGS) -fopenmp -o $@ kthread_test.c ../kthread.c diff --git a/web/server/h2o/libh2o/deps/klib/test/kbit_test.c b/web/server/h2o/libh2o/deps/klib/test/kbit_test.c deleted file mode 100644 index 3ae3bd309..000000000 --- a/web/server/h2o/libh2o/deps/klib/test/kbit_test.c +++ /dev/null @@ -1,137 +0,0 @@ -#include <stdlib.h> -#include <stdio.h> -#include <time.h> -#include <emmintrin.h> -#include "kbit.h" - -// from bowtie-0.9.8.1 -inline static int bt1_pop64(uint64_t x) // the kbi_popcount64() equivalence; similar to popcount_2() in wiki -{ - x -= ((x >> 1) & 0x5555555555555555llu); - x = (x & 0x3333333333333333llu) + ((x >> 2) & 0x3333333333333333llu); - x = (x + (x >> 4)) & 0x0F0F0F0F0F0F0F0Fllu; - x = x + (x >> 8); - x = x + (x >> 16); - x = x + (x >> 32); - return x & 0x3F; -} - -inline static int bt1_countInU64(uint64_t dw, int c) // the kbi_DNAcount64() equivalence -{ - uint64_t dwA = dw & 0xAAAAAAAAAAAAAAAAllu; - uint64_t dwNA = dw & ~0xAAAAAAAAAAAAAAAAllu; - uint64_t tmp; - switch (c) { - case 0: tmp = (dwA >> 1) | dwNA; break; - case 1: tmp = ~(dwA >> 1) & dwNA; break; - case 2: tmp = (dwA >> 1) & ~dwNA; break; - default: tmp = (dwA >> 1) & dwNA; - } - tmp = bt1_pop64(tmp); - if (c == 0) tmp = 32 - tmp; - return (int)tmp; -} - -// from bigmagic -static uint32_t sse2_bit_count32(const __m128i* block, const __m128i* block_end) -{ - const unsigned mu1 = 0x55555555; - const unsigned mu2 = 0x33333333; - const unsigned mu3 = 0x0F0F0F0F; - const unsigned mu4 = 0x0000003F; - - uint32_t tcnt[4]; - - // Loading masks - __m128i m1 = _mm_set_epi32 (mu1, mu1, mu1, mu1); - __m128i m2 = _mm_set_epi32 (mu2, mu2, mu2, mu2); - __m128i m3 = _mm_set_epi32 (mu3, mu3, mu3, mu3); - __m128i m4 = _mm_set_epi32 (mu4, mu4, mu4, mu4); - __m128i mcnt; - mcnt = _mm_xor_si128(m1, m1); // cnt = 0 - - __m128i tmp1, tmp2; - do - { - __m128i b = _mm_load_si128(block); - ++block; - - // b = (b & 0x55555555) + (b >> 1 & 0x55555555); - tmp1 = _mm_srli_epi32(b, 1); // tmp1 = (b >> 1 & 0x55555555) - tmp1 = _mm_and_si128(tmp1, m1); - tmp2 = _mm_and_si128(b, m1); // tmp2 = (b & 0x55555555) - b = _mm_add_epi32(tmp1, tmp2); // b = tmp1 + tmp2 - - // b = (b & 0x33333333) + (b >> 2 & 0x33333333); - tmp1 = _mm_srli_epi32(b, 2); // (b >> 2 & 0x33333333) - tmp1 = _mm_and_si128(tmp1, m2); - tmp2 = _mm_and_si128(b, m2); // (b & 0x33333333) - b = _mm_add_epi32(tmp1, tmp2); // b = tmp1 + tmp2 - - // b = (b + (b >> 4)) & 0x0F0F0F0F; - tmp1 = _mm_srli_epi32(b, 4); // tmp1 = b >> 4 - b = _mm_add_epi32(b, tmp1); // b = b + (b >> 4) - b = _mm_and_si128(b, m3); // & 0x0F0F0F0F - - // b = b + (b >> 8); - tmp1 = _mm_srli_epi32 (b, 8); // tmp1 = b >> 8 - b = _mm_add_epi32(b, tmp1); // b = b + (b >> 8) - - // b = (b + (b >> 16)) & 0x0000003F; - tmp1 = _mm_srli_epi32 (b, 16); // b >> 16 - b = _mm_add_epi32(b, tmp1); // b + (b >> 16) - b = _mm_and_si128(b, m4); // (b >> 16) & 0x0000003F; - - mcnt = _mm_add_epi32(mcnt, b); // mcnt += b - - } while (block < block_end); - - _mm_store_si128((__m128i*)tcnt, mcnt); - - return tcnt[0] + tcnt[1] + tcnt[2] + tcnt[3]; -} - -int main(void) -{ - int i, N = 100000000; - uint64_t *x, cnt; - clock_t t; - int c = 1; - - x = (uint64_t*)calloc(N, 8); - srand48(11); - for (i = 0; i < N; ++i) - x[i] = (uint64_t)lrand48() << 32 ^ lrand48(); - - fprintf(stderr, "\n===> Calculate # of 1 in an integer (popcount) <===\n"); - - t = clock(); cnt = 0; - for (i = 0; i < N; ++i) cnt += kbi_popcount64(x[i]); - fprintf(stderr, "%20s\t%20ld\t%10.6f\n", "kbit", (long)cnt, (double)(clock() - t) / CLOCKS_PER_SEC); - - t = clock(); cnt = 0; - for (i = 0; i < N; ++i) cnt += bt1_pop64(x[i]); - fprintf(stderr, "%20s\t%20ld\t%10.6f\n", "wiki-popcount_2", (long)cnt, (double)(clock() - t) / CLOCKS_PER_SEC); - - t = clock(); cnt = 0; - for (i = 0; i < N; ++i) cnt += __builtin_popcountl(x[i]); - fprintf(stderr, "%20s\t%20ld\t%10.6f\n", "__builtin_popcountl", (long)cnt, (double)(clock() - t) / CLOCKS_PER_SEC); - - t = clock(); cnt = 0; - cnt += sse2_bit_count32((__m128i*)x, (__m128i*)(x+N)); - fprintf(stderr, "%20s\t%20ld\t%10.6f\n", "SSE2-32bit", (long)cnt, (double)(clock() - t) / CLOCKS_PER_SEC); - - fprintf(stderr, "\n===> Count '%c' in 2-bit encoded integers <===\n", "ACGT"[c]); - - t = clock(); cnt = 0; - for (i = 0; i < N; ++i) cnt += kbi_DNAcount64(x[i], c); - fprintf(stderr, "%20s\t%20ld\t%10.6f\n", "kbit", (long)cnt, (double)(clock() - t) / CLOCKS_PER_SEC); - - t = clock(); cnt = 0; - for (i = 0; i < N; ++i) cnt += bt1_countInU64(x[i], c); - fprintf(stderr, "%20s\t%20ld\t%10.6f\n", "bowtie1", (long)cnt, (double)(clock() - t) / CLOCKS_PER_SEC); - - fprintf(stderr, "\n"); - free(x); - return 0; -} diff --git a/web/server/h2o/libh2o/deps/klib/test/kbtree_test.c b/web/server/h2o/libh2o/deps/klib/test/kbtree_test.c deleted file mode 100644 index 8e1068767..000000000 --- a/web/server/h2o/libh2o/deps/klib/test/kbtree_test.c +++ /dev/null @@ -1,94 +0,0 @@ -#include <stdio.h> -#include <assert.h> -#include <time.h> -#include <stdlib.h> -#include <stdint.h> -#include <string.h> - -typedef const char *str_t; - -#include "kbtree.h" -KBTREE_INIT(int, uint32_t, kb_generic_cmp) -KBTREE_INIT(str, str_t, kb_str_cmp) - -static int data_size = 5000000; -static unsigned *int_data; -static char **str_data; - -void ht_init_data() -{ - int i; - char buf[256]; - printf("--- generating data... "); - srand48(11); - int_data = (unsigned*)calloc(data_size, sizeof(unsigned)); - str_data = (char**)calloc(data_size, sizeof(char*)); - for (i = 0; i < data_size; ++i) { - int_data[i] = (unsigned)(data_size * drand48() / 4) * 271828183u; - sprintf(buf, "%x", int_data[i]); - str_data[i] = strdup(buf); - } - printf("done!\n"); -} -void ht_destroy_data() -{ - int i; - for (i = 0; i < data_size; ++i) free(str_data[i]); - free(str_data); free(int_data); -} - -void ht_khash_int() -{ - int i; - unsigned *data = int_data; - uint32_t *l, *u; - kbtree_t(int) *h; - - h = kb_init(int, KB_DEFAULT_SIZE); - for (i = 0; i < data_size; ++i) { - if (kb_get(int, h, data[i]) == 0) kb_put(int, h, data[i]); - else kb_del(int, h, data[i]); - } - printf("[ht_khash_int] size: %d\n", kb_size(h)); - if (1) { - int cnt = 0; - uint32_t x, y; - kb_interval(int, h, 2174625464u, &l, &u); - printf("interval for 2174625464: (%u, %u)\n", l? *l : 0, u? *u : 0); -#define traverse_f(p) { if (cnt == 0) y = *p; ++cnt; } - __kb_traverse(uint32_t, h, traverse_f); - __kb_get_first(uint32_t, h, x); - printf("# of elements from traversal: %d\n", cnt); - printf("first element: %d == %d\n", x, y); - } - __kb_destroy(h); -} -void ht_khash_str() -{ - int i; - char **data = str_data; - kbtree_t(str) *h; - - h = kb_init(str, KB_DEFAULT_SIZE); - for (i = 0; i < data_size; ++i) { - if (kb_get(str, h, data[i]) == 0) kb_put(str, h, data[i]); - else kb_del(str, h, data[i]); - } - printf("[ht_khash_int] size: %d\n", kb_size(h)); - __kb_destroy(h); -} -void ht_timing(void (*f)(void)) -{ - clock_t t = clock(); - (*f)(); - printf("[ht_timing] %.3lf sec\n", (double)(clock() - t) / CLOCKS_PER_SEC); -} -int main(int argc, char *argv[]) -{ - if (argc > 1) data_size = atoi(argv[1]); - ht_init_data(); - ht_timing(ht_khash_int); - ht_timing(ht_khash_str); - ht_destroy_data(); - return 0; -} diff --git a/web/server/h2o/libh2o/deps/klib/test/kgraph_test.c b/web/server/h2o/libh2o/deps/klib/test/kgraph_test.c deleted file mode 100644 index 3da1cd71b..000000000 --- a/web/server/h2o/libh2o/deps/klib/test/kgraph_test.c +++ /dev/null @@ -1,26 +0,0 @@ -#include <stdio.h> -#include "kgraph.h" - -KHASH_INIT2(e32, extern, uint32_t, int, 1, kh_int_hash_func, kh_int_hash_equal) - -typedef struct { - int i; - khash_t(e32) *_arc; -} vertex_t; - -KGRAPH_INIT(g, extern, vertex_t, int, e32) -KGRAPH_PRINT(g, extern) - -int main() -{ - int *pb, *pe; - kgraph_t(g) *g; - g = kg_init_g(); - kg_put_a_g(g, 10, 20, 0, &pb, &pe); - kg_put_a_g(g, 20, 30, 0, &pb, &pe); - kg_put_a_g(g, 30, 10, 1, &pb, &pe); - kg_del_v_g(g, 20); - kg_print_g(g); - kg_destroy_g(g); - return 0; -} diff --git a/web/server/h2o/libh2o/deps/klib/test/khash_keith.c b/web/server/h2o/libh2o/deps/klib/test/khash_keith.c deleted file mode 100644 index ddd755ac7..000000000 --- a/web/server/h2o/libh2o/deps/klib/test/khash_keith.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * This is an optimized version of the following C++ program: - * - * http://keithlea.com/javabench/src/cpp/hash.cpp - * - * Keith in his benchmark (http://keithlea.com/javabench/data) showed that the - * Java implementation is twice as fast as the C++ version. In fact, this is - * only because the C++ implementation is substandard. Most importantly, Keith - * is using "sprintf()" to convert an integer to a string, which is known to be - * extremely inefficient. - */ -#include <stdio.h> -#include "khash.h" -KHASH_MAP_INIT_STR(str, int) - -inline void int2str(int c, int base, char *ret) -{ - const char *tab = "0123456789abcdef"; - if (c == 0) ret[0] = '0', ret[1] = 0; - else { - int l, x, y; - char buf[16]; - for (l = 0, x = c < 0? -c : c; x > 0; x /= base) buf[l++] = tab[x%base]; - if (c < 0) buf[l++] = '-'; - for (x = l - 1, y = 0; x >= 0; --x) ret[y++] = buf[x]; - ret[y] = 0; - } -} - -#ifndef _USE_STRDUP -#define BLOCK_SIZE 0x100000 -int main(int argc, char *argv[]) -{ - char **mem = 0; - int i, l, n = 1000000, ret, block_end = 0, curr = 0, c = 0; - khash_t(str) *h; - h = kh_init(str); - if (argc > 1) n = atoi(argv[1]); - mem = malloc(sizeof(void*)); - mem[0] = malloc(BLOCK_SIZE); // memory buffer to avoid memory fragmentation - curr = block_end = 0; - for (i = 1; i <= n; ++i) { - char buf[16]; - int2str(i, 16, buf); - khint_t k = kh_put(str, h, buf, &ret); - l = strlen(buf) + 1; - if (block_end + l > BLOCK_SIZE) { - ++curr; block_end = 0; - mem = realloc(mem, (curr + 1) * sizeof(void*)); - mem[curr] = malloc(BLOCK_SIZE); - } - memcpy(mem[curr] + block_end, buf, l); - kh_key(h, k) = mem[curr] + block_end; - block_end += l; - kh_val(h, k) = i; - } - for (i = 1; i <= n; ++i) { - char buf[16]; - int2str(i, 10, buf); - khint_t k = kh_get(str, h, buf); - if (k != kh_end(h)) ++c; - } - printf("%d\n", c); - for (ret = 0; ret <= curr; ++ret) free(mem[ret]); - free(mem); - kh_destroy(str, h); - return 0; -} -#else // _USE_STRDUP -int main(int argc, char *argv[]) -{ - int i, l, n = 1000000, ret, c = 0; - khash_t(str) *h; - khint_t k; - h = kh_init(str); - if (argc > 1) n = atoi(argv[1]); - for (i = 1; i <= n; ++i) { - char buf[16]; - int2str(i, 16, buf); - k = kh_put(str, h, strdup(buf), &ret); - kh_val(h, k) = i; - } - for (i = 1; i <= n; ++i) { - char buf[16]; - int2str(i, 10, buf); - k = kh_get(str, h, buf); - if (k != kh_end(h)) ++c; - } - for (k = kh_begin(h); k != kh_end(h); ++k) // explicitly freeing memory takes 10-20% CPU time. - if (kh_exist(h, k)) free((char*)kh_key(h, k)); - printf("%d\n", c); - kh_destroy(str, h); - return 0; -} -#endif diff --git a/web/server/h2o/libh2o/deps/klib/test/khash_keith2.c b/web/server/h2o/libh2o/deps/klib/test/khash_keith2.c deleted file mode 100644 index b9df9b7c1..000000000 --- a/web/server/h2o/libh2o/deps/klib/test/khash_keith2.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * This is an optimized version of the following C++ program: - * - * http://keithlea.com/javabench/src/cpp/hash.cpp - * - * Keith in his benchmark (http://keithlea.com/javabench/data) showed that the - * Java implementation is twice as fast as the C++ version. In fact, this is - * only because the C++ implementation is substandard. Most importantly, Keith - * is using "sprintf()" to convert an integer to a string, which is known to be - * extremely inefficient. - */ -#include <stdio.h> -#include "khash.h" -KHASH_MAP_INIT_STR(str, int) - -inline void int2str(int c, int base, char *ret) -{ - const char *tab = "0123456789abcdef"; - if (c == 0) ret[0] = '0', ret[1] = 0; - else { - int l, x, y; - char buf[16]; - for (l = 0, x = c < 0? -c : c; x > 0; x /= base) buf[l++] = tab[x%base]; - if (c < 0) buf[l++] = '-'; - for (x = l - 1, y = 0; x >= 0; --x) ret[y++] = buf[x]; - ret[y] = 0; - } -} - -int main(int argc, char *argv[]) -{ - int i, l, n = 1000, ret; - khash_t(str) *h, *h2; - khint_t k; - h = kh_init(str); - h2 = kh_init(str); - if (argc > 1) n = atoi(argv[1]); - for (i = 0; i < 10000; ++i) { - char buf[32]; - strcpy(buf, "foo_"); - int2str(i, 10, buf+4); - k = kh_put(str, h, strdup(buf), &ret); - kh_val(h, k) = i; - } - for (i = 0; i < n; ++i) { - for (k = kh_begin(h); k != kh_end(h); ++k) { - if (kh_exist(h, k)) { - khint_t k2 = kh_put(str, h2, kh_key(h, k), &ret); - if (ret) { // absent - kh_key(h2, k2) = strdup(kh_key(h, k)); - kh_val(h2, k2) = kh_val(h, k); - } else kh_val(h2, k2) += kh_val(h, k); - } - } - } - k = kh_get(str, h, "foo_1"); printf("%d", kh_val(h, k)); - k = kh_get(str, h, "foo_9999"); printf(" %d", kh_val(h, k)); - k = kh_get(str, h2, "foo_1"); printf(" %d", kh_val(h2, k)); - k = kh_get(str, h2, "foo_9999"); printf(" %d\n", kh_val(h2, k)); - for (k = kh_begin(h); k != kh_end(h); ++k) - if (kh_exist(h, k)) free((char*)kh_key(h, k)); - for (k = kh_begin(h2); k != kh_end(h2); ++k) - if (kh_exist(h2, k)) free((char*)kh_key(h2, k)); - kh_destroy(str, h); - kh_destroy(str, h2); - return 0; -} diff --git a/web/server/h2o/libh2o/deps/klib/test/khash_test.c b/web/server/h2o/libh2o/deps/klib/test/khash_test.c deleted file mode 100644 index 8d6687ff4..000000000 --- a/web/server/h2o/libh2o/deps/klib/test/khash_test.c +++ /dev/null @@ -1,141 +0,0 @@ -#include <stdio.h> -#include <assert.h> -#include <time.h> -#include <stdlib.h> -#include <string.h> - -#include "khash.h" -KHASH_SET_INIT_STR(str) -KHASH_MAP_INIT_INT(int, unsigned char) - -typedef struct { - unsigned key; - unsigned char val; -} int_unpack_t; - -typedef struct { - unsigned key; - unsigned char val; -} __attribute__ ((__packed__)) int_packed_t; - -#define hash_eq(a, b) ((a).key == (b).key) -#define hash_func(a) ((a).key) - -KHASH_INIT(iun, int_unpack_t, char, 0, hash_func, hash_eq) -KHASH_INIT(ipk, int_packed_t, char, 0, hash_func, hash_eq) - -static int data_size = 5000000; -static unsigned *int_data; -static char **str_data; - -void ht_init_data() -{ - int i; - char buf[256]; - khint32_t x = 11; - printf("--- generating data... "); - int_data = (unsigned*)calloc(data_size, sizeof(unsigned)); - str_data = (char**)calloc(data_size, sizeof(char*)); - for (i = 0; i < data_size; ++i) { - int_data[i] = (unsigned)(data_size * ((double)x / UINT_MAX) / 4) * 271828183u; - sprintf(buf, "%x", int_data[i]); - str_data[i] = strdup(buf); - x = 1664525L * x + 1013904223L; - } - printf("done!\n"); -} - -void ht_destroy_data() -{ - int i; - for (i = 0; i < data_size; ++i) free(str_data[i]); - free(str_data); free(int_data); -} - -void ht_khash_int() -{ - int i, ret; - unsigned *data = int_data; - khash_t(int) *h; - unsigned k; - - h = kh_init(int); - for (i = 0; i < data_size; ++i) { - k = kh_put(int, h, data[i], &ret); - kh_val(h, k) = i&0xff; - if (!ret) kh_del(int, h, k); - } - printf("[ht_khash_int] size: %u\n", kh_size(h)); - kh_destroy(int, h); -} - -void ht_khash_str() -{ - int i, ret; - char **data = str_data; - khash_t(str) *h; - unsigned k; - - h = kh_init(str); - for (i = 0; i < data_size; ++i) { - k = kh_put(str, h, data[i], &ret); - if (!ret) kh_del(str, h, k); - } - printf("[ht_khash_int] size: %u\n", kh_size(h)); - kh_destroy(str, h); -} - -void ht_khash_unpack() -{ - int i, ret; - unsigned *data = int_data; - khash_t(iun) *h; - unsigned k; - - h = kh_init(iun); - for (i = 0; i < data_size; ++i) { - int_unpack_t x; - x.key = data[i]; x.val = i&0xff; - k = kh_put(iun, h, x, &ret); - if (!ret) kh_del(iun, h, k); - } - printf("[ht_khash_unpack] size: %u (sizeof=%ld)\n", kh_size(h), sizeof(int_unpack_t)); - kh_destroy(iun, h); -} - -void ht_khash_packed() -{ - int i, ret; - unsigned *data = int_data; - khash_t(ipk) *h; - unsigned k; - - h = kh_init(ipk); - for (i = 0; i < data_size; ++i) { - int_packed_t x; - x.key = data[i]; x.val = i&0xff; - k = kh_put(ipk, h, x, &ret); - if (!ret) kh_del(ipk, h, k); - } - printf("[ht_khash_packed] size: %u (sizeof=%ld)\n", kh_size(h), sizeof(int_packed_t)); - kh_destroy(ipk, h); -} - -void ht_timing(void (*f)(void)) -{ - clock_t t = clock(); - (*f)(); - printf("[ht_timing] %.3lf sec\n", (double)(clock() - t) / CLOCKS_PER_SEC); -} - -int main(int argc, char *argv[]) -{ - if (argc > 1) data_size = atoi(argv[1]); - ht_init_data(); - ht_timing(ht_khash_int); - ht_timing(ht_khash_str); - ht_timing(ht_khash_unpack); - ht_timing(ht_khash_packed); - ht_destroy_data(); - return 0; -} diff --git a/web/server/h2o/libh2o/deps/klib/test/klist_test.c b/web/server/h2o/libh2o/deps/klib/test/klist_test.c deleted file mode 100644 index cd13813df..000000000 --- a/web/server/h2o/libh2o/deps/klib/test/klist_test.c +++ /dev/null @@ -1,19 +0,0 @@ -#include <stdio.h> -#include "klist.h" - -#define __int_free(x) -KLIST_INIT(32, int, __int_free) - -int main() -{ - klist_t(32) *kl; - kliter_t(32) *p; - kl = kl_init(32); - *kl_pushp(32, kl) = 1; - *kl_pushp(32, kl) = 10; - kl_shift(32, kl, 0); - for (p = kl_begin(kl); p != kl_end(kl); p = kl_next(p)) - printf("%d\n", kl_val(p)); - kl_destroy(32, kl); - return 0; -} diff --git a/web/server/h2o/libh2o/deps/klib/test/kmin_test.c b/web/server/h2o/libh2o/deps/klib/test/kmin_test.c deleted file mode 100644 index 33ccd1cbc..000000000 --- a/web/server/h2o/libh2o/deps/klib/test/kmin_test.c +++ /dev/null @@ -1,48 +0,0 @@ -#include <stdio.h> -#include <math.h> -#include "kmath.h" - -static int n_evals; - -double f_Chebyquad(int n, double *x, void *data) -{ - int i, j; - double y[20][20], f; - int np, iw; - double sum; - for (j = 0; j != n; ++j) { - y[0][j] = 1.; - y[1][j] = 2. * x[j] - 1.; - } - for (i = 1; i != n; ++i) - for (j = 0; j != n; ++j) - y[i+1][j] = 2. * y[1][j] * y[i][j] - y[i-1][j]; - f = 0.; - np = n + 1; - iw = 1; - for (i = 0; i != np; ++i) { - sum = 0.; - for (j = 0; j != n; ++j) sum += y[i][j]; - sum /= n; - if (iw > 0) sum += 1. / ((i - 1) * (i + 1)); - iw = -iw; - f += sum * sum; - } - ++n_evals; - return f; -} - -int main() -{ - double x[20], y; - int n, i; - printf("\nMinimizer: Hooke-Jeeves\n"); - for (n = 2; n <= 8; n += 2) { - for (i = 0; i != n; ++i) x[i] = (double)(i + 1) / n; - n_evals = 0; - y = kmin_hj(f_Chebyquad, n, x, 0, KMIN_RADIUS, KMIN_EPS, KMIN_MAXCALL); - printf("n=%d,min=%.8lg,n_evals=%d\n", n, y, n_evals); - } - printf("\n"); - return 0; -} diff --git a/web/server/h2o/libh2o/deps/klib/test/kseq_bench.c b/web/server/h2o/libh2o/deps/klib/test/kseq_bench.c deleted file mode 100644 index eeda13f71..000000000 --- a/web/server/h2o/libh2o/deps/klib/test/kseq_bench.c +++ /dev/null @@ -1,69 +0,0 @@ -#include <zlib.h> -#include <stdio.h> -#include <time.h> -#include <stdint.h> -#include <stdlib.h> -#include "kseq.h" - -#define BUF_SIZE 4096 -KSTREAM_INIT(gzFile, gzread, BUF_SIZE) - -int main(int argc, char *argv[]) -{ - gzFile fp; - clock_t t; - if (argc == 1) { - fprintf(stderr, "Usage: kseq_bench <in.gz>\n"); - return 1; - } - { - uint8_t *buf = malloc(BUF_SIZE); - fp = gzopen(argv[1], "r"); - t = clock(); - while (gzread(fp, buf, BUF_SIZE) > 0); - fprintf(stderr, "[gzread] %.2f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); - gzclose(fp); - free(buf); - } - { - kstream_t *ks; - fp = gzopen(argv[1], "r"); - ks = ks_init(fp); - t = clock(); - while (ks_getc(ks) >= 0); - fprintf(stderr, "[ks_getc] %.2f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); - ks_destroy(ks); - gzclose(fp); - } - { - kstream_t *ks; - kstring_t *s; - int dret; - s = calloc(1, sizeof(kstring_t)); - fp = gzopen(argv[1], "r"); - ks = ks_init(fp); - t = clock(); - while (ks_getuntil(ks, '\n', s, &dret) >= 0); - fprintf(stderr, "[ks_getuntil] %.2f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); - ks_destroy(ks); - gzclose(fp); - free(s->s); free(s); - } - if (argc == 2) { - fp = gzopen(argv[1], "r"); - t = clock(); - while (gzgetc(fp) >= 0); - fprintf(stderr, "[gzgetc] %.2f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); - gzclose(fp); - } - if (argc == 2) { - char *buf = malloc(BUF_SIZE); - fp = gzopen(argv[1], "r"); - t = clock(); - while (gzgets(fp, buf, BUF_SIZE) > 0); - fprintf(stderr, "[gzgets] %.2f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); - gzclose(fp); - free(buf); - } - return 0; -} diff --git a/web/server/h2o/libh2o/deps/klib/test/kseq_bench2.c b/web/server/h2o/libh2o/deps/klib/test/kseq_bench2.c deleted file mode 100644 index b4154583b..000000000 --- a/web/server/h2o/libh2o/deps/klib/test/kseq_bench2.c +++ /dev/null @@ -1,43 +0,0 @@ -#include <stdio.h> -#include <time.h> -#include <stdint.h> -#include <stdlib.h> -#include <fcntl.h> -#include "kseq.h" -KSTREAM_INIT(int, read, 4096) - -#define BUF_SIZE 65536 - -int main(int argc, char *argv[]) -{ - clock_t t; - if (argc == 1) { - fprintf(stderr, "Usage: %s <in.txt>\n", argv[0]); - return 1; - } - { - FILE *fp; - char *s; - t = clock(); - s = malloc(BUF_SIZE); - fp = fopen(argv[1], "r"); - while (fgets(s, BUF_SIZE, fp)); - fclose(fp); - fprintf(stderr, "[fgets] %.2f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); - } - { - int fd, dret; - kstream_t *ks; - kstring_t s; - t = clock(); - s.l = s.m = 0; s.s = 0; - fd = open(argv[1], O_RDONLY); - ks = ks_init(fd); - while (ks_getuntil(ks, '\n', &s, &dret) >= 0); - free(s.s); - ks_destroy(ks); - close(fd); - fprintf(stderr, "[kstream] %.2f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); - } - return 0; -} diff --git a/web/server/h2o/libh2o/deps/klib/test/kseq_test.c b/web/server/h2o/libh2o/deps/klib/test/kseq_test.c deleted file mode 100644 index 0304dea35..000000000 --- a/web/server/h2o/libh2o/deps/klib/test/kseq_test.c +++ /dev/null @@ -1,27 +0,0 @@ -#include <zlib.h> -#include <stdio.h> -#include "kseq.h" -KSEQ_INIT(gzFile, gzread) - -int main(int argc, char *argv[]) -{ - gzFile fp; - kseq_t *seq; - int l; - if (argc == 1) { - fprintf(stderr, "Usage: %s <in.fasta>\n", argv[0]); - return 1; - } - fp = gzopen(argv[1], "r"); - seq = kseq_init(fp); - while ((l = kseq_read(seq)) >= 0) { - printf("name: %s\n", seq->name.s); - if (seq->comment.l) printf("comment: %s\n", seq->comment.s); - printf("seq: %s\n", seq->seq.s); - if (seq->qual.l) printf("qual: %s\n", seq->qual.s); - } - printf("return value: %d\n", l); - kseq_destroy(seq); - gzclose(fp); - return 0; -} diff --git a/web/server/h2o/libh2o/deps/klib/test/kseq_test.dat b/web/server/h2o/libh2o/deps/klib/test/kseq_test.dat deleted file mode 100644 index b774ae289..000000000 --- a/web/server/h2o/libh2o/deps/klib/test/kseq_test.dat +++ /dev/null @@ -1,12 +0,0 @@ ->1 -acgtacgtacgtagc ->2 test -acgatcgatc -@3 test2 -cgctagcatagc -cgatatgactta -+ -78wo82usd980 -d88fau - -238ud8 diff --git a/web/server/h2o/libh2o/deps/klib/test/ksort_test.c b/web/server/h2o/libh2o/deps/klib/test/ksort_test.c deleted file mode 100644 index 92c7d3d16..000000000 --- a/web/server/h2o/libh2o/deps/klib/test/ksort_test.c +++ /dev/null @@ -1,104 +0,0 @@ -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -#include <time.h> -#include "ksort.h" - -KSORT_INIT_GENERIC(int) - -int main(int argc, char *argv[]) -{ - int i, N = 10000000; - int *array, x; - clock_t t1, t2; - if (argc > 1) N = atoi(argv[1]); - array = (int*)malloc(sizeof(int) * N); - - srand48(11); - for (i = 0; i < N; ++i) array[i] = (int)lrand48(); - t1 = clock(); - x = ks_ksmall(int, N, array, 10500); - t2 = clock(); - fprintf(stderr, "ksmall [%d]: %.3lf\n", x, (double)(t2-t1)/CLOCKS_PER_SEC); - - srand48(11); - for (i = 0; i < N; ++i) array[i] = (int)lrand48(); - t1 = clock(); - ks_introsort(int, N, array); - t2 = clock(); - fprintf(stderr, "introsort [%d]: %.3lf\n", array[10500], (double)(t2-t1)/CLOCKS_PER_SEC); - for (i = 0; i < N-1; ++i) { - if (array[i] > array[i+1]) { - fprintf(stderr, "Bug in introsort!\n"); - exit(1); - } - } - -#ifndef _ALIGNED_ONLY - { // test unaligned ksmall - srand48(11); - unsigned char *a; - int *b; - a = malloc(N * sizeof(int) + 1); - b = (int*)(a + 1); - for (i = 0; i < N; ++i) b[i] = (int)lrand48(); - t1 = clock(); - ks_introsort(int, N, b); - t2 = clock(); - fprintf(stderr, "introsort [%d]: %.3lf (unaligned: 0x%lx) \n", b[10500], (double)(t2-t1)/CLOCKS_PER_SEC, (size_t)b); - } -#endif - - t1 = clock(); - ks_introsort(int, N, array); - t2 = clock(); - fprintf(stderr, "introsort (sorted): %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); - - srand48(11); - for (i = 0; i < N; ++i) array[i] = (int)lrand48(); - t1 = clock(); - ks_combsort(int, N, array); - t2 = clock(); - fprintf(stderr, "combsort: %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); - for (i = 0; i < N-1; ++i) { - if (array[i] > array[i+1]) { - fprintf(stderr, "Bug in combsort!\n"); - exit(1); - } - } - - srand48(11); - for (i = 0; i < N; ++i) array[i] = (int)lrand48(); - t1 = clock(); - ks_mergesort(int, N, array, 0); - t2 = clock(); - fprintf(stderr, "mergesort: %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); - for (i = 0; i < N-1; ++i) { - if (array[i] > array[i+1]) { - fprintf(stderr, "Bug in mergesort!\n"); - exit(1); - } - } - - t1 = clock(); - ks_mergesort(int, N, array, 0); - t2 = clock(); - fprintf(stderr, "mergesort (sorted): %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); - - srand48(11); - for (i = 0; i < N; ++i) array[i] = (int)lrand48(); - t1 = clock(); - ks_heapmake(int, N, array); - ks_heapsort(int, N, array); - t2 = clock(); - fprintf(stderr, "heapsort: %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); - for (i = 0; i < N-1; ++i) { - if (array[i] > array[i+1]) { - fprintf(stderr, "Bug in heapsort!\n"); - exit(1); - } - } - - free(array); - return 0; -} diff --git a/web/server/h2o/libh2o/deps/klib/test/ksort_test.cc b/web/server/h2o/libh2o/deps/klib/test/ksort_test.cc deleted file mode 100644 index 8950d8064..000000000 --- a/web/server/h2o/libh2o/deps/klib/test/ksort_test.cc +++ /dev/null @@ -1,997 +0,0 @@ -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -#include <time.h> -#include <algorithm> - -#include "ksort.h" -KSORT_INIT_GENERIC(int) - -using namespace std; - -/********************************** - * BEGIN OF PAUL'S IMPLEMENTATION * - **********************************/ - -/* Attractive Chaos: I have added inline where necessary. */ - -/* -Copyright (c) 2004 Paul Hsieh -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 sorttest 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 FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. -*/ - -/* - -Recommended flags: ------------------- - -Intel C/C++: -icl /O2 /G6 /Qaxi /Qxi /Qip sorttest.c - -WATCOM C/C++: -wcl386 /otexan /6r sorttest.c - -GCC: -gcc -O3 -mcpu=athlon-xp -march=athlon-xp sorttest.c - -MSVC: -cl /O2 /Ot /Og /G6 sorttest.c - -*/ - -static inline void sort2 (int * numbers) { -int tmp; - - if (numbers[0] <= numbers[1]) return; - tmp = numbers[0]; - numbers[0] = numbers[1]; - numbers[1] = tmp; -} - -static inline void sort3 (int * numbers) { -int tmp; - - if (numbers[0] <= numbers[1]) { - if (numbers[1] <= numbers[2]) return; - if (numbers[2] <= numbers[0]) { - tmp = numbers[0]; - numbers[0] = numbers[2]; - numbers[2] = numbers[1]; - numbers[1] = tmp; - return; - } - tmp = numbers[1]; - } else { - tmp = numbers[0]; - if (numbers[0] <= numbers[2]) { - numbers[0] = numbers[1]; - numbers[1] = tmp; - return; - } - if (numbers[2] <= numbers[1]) { - numbers[0] = numbers[2]; - numbers[2] = tmp; - return; - } - numbers[0] = numbers[1]; - } - numbers[1] = numbers[2]; - numbers[2] = tmp; -} - -static inline void sort4 (int * num) { -int tmp; - if (num[0] < num[1]) { - if (num[1] < num[2]) { - if (num[1] < num[3]) { - if (num[2] >= num[3]) { - tmp = num[2]; - num[2] = num[3]; - num[3] = tmp; - } - } else { - tmp = num[1]; - if (num[0] < num[3]) { - num[1] = num[3]; - } else { - num[1] = num[0]; - num[0] = num[3]; - } - num[3] = num[2]; - num[2] = tmp; - } - } else { - if (num[0] < num[2]) { - if (num[2] < num[3]) { - if (num[1] < num[3]) { - tmp = num[1]; - } else { - tmp = num[3]; - num[3] = num[1]; - } - num[1] = num[2]; - num[2] = tmp; - } else { - if (num[0] < num[3]) { - tmp = num[3]; - } else { - tmp = num[0]; - num[0] = num[3]; - } - num[3] = num[1]; - num[1] = tmp; - } - } else { - if (num[0] < num[3]) { - tmp = num[0]; - num[0] = num[2]; - if (num[1] < num[3]) { - num[2] = num[1]; - } else { - num[2] = num[3]; - num[3] = num[1]; - } - num[1] = tmp; - } else { - if (num[2] < num[3]) { - tmp = num[0]; - num[0] = num[2]; - num[2] = tmp; - tmp = num[1]; - num[1] = num[3]; - } else { - tmp = num[1]; - num[1] = num[2]; - num[2] = num[0]; - num[0] = num[3]; - } - num[3] = tmp; - } - } - } - } else { - tmp = num[0]; - if (tmp < num[2]) { - if (tmp < num[3]) { - num[0] = num[1]; - num[1] = tmp; - if (num[2] >= num[3]) { - tmp = num[2]; - num[2] = num[3]; - num[3] = tmp; - } - } else { - if (num[1] < num[3]) { - num[0] = num[1]; - num[1] = num[3]; - } else { - num[0] = num[3]; - } - num[3] = num[2]; - num[2] = tmp; - } - } else { - if (num[1] < num[2]) { - if (num[2] < num[3]) { - num[0] = num[1]; - num[1] = num[2]; - if (tmp < num[3]) { - num[2] = tmp; - } else { - num[2] = num[3]; - num[3] = tmp; - } - } else { - if (num[1] < num[3]) { - num[0] = num[1]; - num[1] = num[3]; - } else { - num[0] = num[3]; - } - num[3] = tmp; - } - } else { - if (num[1] < num[3]) { - num[0] = num[2]; - if (tmp < num[3]) { - num[2] = tmp; - } else { - num[2] = num[3]; - num[3] = tmp; - } - } else { - if (num[2] < num[3]) { - num[0] = num[2]; - num[2] = num[1]; - num[1] = num[3]; - num[3] = tmp; - } else { - num[0] = num[3]; - num[3] = tmp; - tmp = num[1]; - num[1] = num[2]; - num[2] = tmp; - } - } - } - } - } -} - -static inline void sortAlt2 (int * numbers, int * altNumbers) { - if (numbers[0] <= numbers[1]) { - altNumbers[0] = numbers[0]; - altNumbers[1] = numbers[1]; - } else { - altNumbers[0] = numbers[1]; - altNumbers[1] = numbers[0]; - } -} - -static inline void sortAlt3 (int * numbers, int * altNumbers) { - if (numbers[0] <= numbers[1]) { - if (numbers[1] <= numbers[2]) { - altNumbers[0] = numbers[0]; - altNumbers[1] = numbers[1]; - altNumbers[2] = numbers[2]; - } else if (numbers[2] <= numbers[0]) { - altNumbers[0] = numbers[2]; - altNumbers[1] = numbers[0]; - altNumbers[2] = numbers[1]; - } else { - altNumbers[0] = numbers[0]; - altNumbers[1] = numbers[2]; - altNumbers[2] = numbers[1]; - } - } else { - if (numbers[0] <= numbers[2]) { - altNumbers[0] = numbers[1]; - altNumbers[1] = numbers[0]; - altNumbers[2] = numbers[2]; - } else if (numbers[2] <= numbers[1]) { - altNumbers[0] = numbers[2]; - altNumbers[1] = numbers[1]; - altNumbers[2] = numbers[0]; - } else { - altNumbers[0] = numbers[1]; - altNumbers[1] = numbers[2]; - altNumbers[2] = numbers[0]; - } - } -} - -/* - * Insert Sort - */ - -inline void insertSort (int numbers[], int qty) { -int i, j, idx, q4; -int tmp; - - if (qty <= 4) { - if (qty == 4) sort4 (numbers); - else if (qty == 3) sort3 (numbers); - else if (qty == 2) sort2 (numbers); - return; - } - - q4 = qty - 4; - - for (i=0; i < q4; i++) { - idx = i; - for (j=i+1; j < qty; j++) { - if (numbers[j] < numbers[idx]) idx = j; - } - if (idx != i) { - tmp = numbers[idx]; - numbers[idx] = numbers[i]; - numbers[i] = tmp; - } - } - - sort4 (numbers + q4); -} - -/* - * Heap Sort - */ - -/* Assure the heap property for entries from top to last */ -static void siftDown (int numbers[], int top, int last) { -int tmp = numbers[top]; -int maxIdx = top; - - while (last >= (maxIdx += maxIdx)) { - - /* This is where the comparison occurrs and where a sufficiently - good compiler can use a computed conditional result rather - than using control logic. */ - if (maxIdx != last && numbers[maxIdx] < numbers[maxIdx + 1]) maxIdx++; - - if (tmp >= numbers[maxIdx]) break; - numbers[top] = numbers[maxIdx]; - top = maxIdx; - } - numbers[top] = tmp; -} - -/* Peel off the top siftDown operation since its parameters are trivial to - fill in directly (and this saves us some moves.) */ -static void siftDown0 (int numbers[], int last) { -int tmp; - - if (numbers[0] < numbers[1]) { - tmp = numbers[1]; - numbers[1] = numbers[0]; - siftDown (numbers, 1, last); - } else { - tmp = numbers[0]; - } - numbers[0] = numbers[last]; - numbers[last] = tmp; -} - -void heapSort (int numbers[], int qty) { -int i; - - if (qty <= 4) { - if (qty == 4) sort4 (numbers); - else if (qty == 3) sort3 (numbers); - else if (qty == 2) sort2 (numbers); - return; - } - - i = qty / 2; - /* Enforce the heap property for each position in the tree */ - for ( qty--; i > 0; i--) siftDown (numbers, i, qty); - for (i = qty; i > 0; i--) siftDown0 (numbers, i); -} - -/* - * Quick Sort - */ - -static int medianOf3 (int * numbers, int i, int j) { -int tmp; - - if (numbers[0] <= numbers[i]) { - if (numbers[j] <= numbers[0]) return numbers[0]; /* j 0 i */ - if (numbers[i] <= numbers[j]) j = i; /* 0 i j */ - /* 0 j i */ - } else { - if (numbers[0] <= numbers[j]) return numbers[0]; /* i 0 j */ - if (numbers[j] <= numbers[i]) j = i; /* j i 0 */ - /* i j 0 */ - } - tmp = numbers[j]; - numbers[j] = numbers[0]; - numbers[0] = tmp; - return tmp; -} - -static void quickSortRecurse (int * numbers, int left, int right) { -int pivot, lTmp, rTmp; - - qsrStart:; - -#if defined(__GNUC__) - if (right <= left + 8) { - insertSort (numbers + left, right - left + 1); - return; - } -#else - if (right <= left + 3) { - if (right == left + 1) { - sort2 (numbers + left); - } else if (right == left + 2) { - sort3 (numbers + left); - } else if (right == left + 3) { - sort4 (numbers + left); - } - return; - } -#endif - - lTmp = left; - rTmp = right; - - pivot = medianOf3 (numbers + left, (right-left) >> 1, right-1-left); - - goto QStart; - while (1) { - do { - right--; - if (left >= right) goto QEnd; - QStart:; - } while (numbers[right] > pivot); - numbers[left] = numbers[right]; - do { - left++; - if (left >= right) { - left = right; - goto QEnd; - } - } while (numbers[ left] < pivot); - numbers[right] = numbers[left]; - } - QEnd:; - numbers[left] = pivot; - - /* Only recurse the smaller partition */ - - if (left-1 - lTmp <= rTmp - left - 1) { - if (lTmp < left) quickSortRecurse (numbers, lTmp, left-1); - - /* Set up for larger partition */ - left++; - right = rTmp; - } else { - if (rTmp > left) quickSortRecurse (numbers, left+1, rTmp); - - /* Set up for larger partition */ - right = left - 1; - left = lTmp; - } - - /* Rerun with larger partition (recursion not required.) */ - goto qsrStart; -} - -void quickSort (int numbers[], int qty) { - if (qty < 2) return; - quickSortRecurse (numbers, 0, qty - 1); -} - -/* - * Merge Sort - */ - -static void mergesortInPlace (int * numbers, int * altNumbers, int qty); - -/* Perform mergesort, but store results in altNumbers */ - -static void mergesortExchange (int * numbers, int * altNumbers, int qty) { -int half, i0, i1, i; - - if (qty == 2) { - sortAlt2 (numbers, altNumbers); - return; - } - if (qty == 3) { - sortAlt3 (numbers, altNumbers); - return; - } - - half = (qty + 1)/2; - - mergesortInPlace (numbers, altNumbers, half); - mergesortInPlace (numbers + half, altNumbers, qty - half); - - i0 = 0; i1 = half; - - for (i=0; i < qty; i++) { - if (i1 >= qty || (i0 < half && numbers[i0] < numbers[i1])) { - altNumbers[i] = numbers[i0]; - i0++; - } else { - altNumbers[i] = numbers[i1]; - i1++; - } - } -} - -/* Perform mergesort and store results in numbers */ - -static void mergesortInPlace (int * numbers, int * altNumbers, int qty) { -int half, i0, i1, i; - -#if 0 - if (qty == 2) { - sort2 (numbers); - return; - } - if (qty == 3) { - sort3 (numbers); - return; - } - if (qty == 4) { - sort4 (numbers); - return; - } -#else - if (qty <= 12) { - insertSort (numbers, qty); - return; - } -#endif - - half = (qty + 1)/2; - - mergesortExchange (numbers, altNumbers, half); - mergesortExchange (numbers + half, altNumbers + half, qty - half); - - i0 = 0; i1 = half; - - for (i=0; i < qty; i++) { - if (i1 >= qty || (i0 < half && altNumbers[i0] < altNumbers[i1])) { - numbers[i] = altNumbers[i0]; - i0++; - } else { - numbers[i] = altNumbers[i1]; - i1++; - } - } -} - -#include <stdlib.h> - -void mergeSort (int numbers[], int qty) { -int * tmpArray; - - if (qty <= 12) { - insertSort (numbers, qty); - return; - } - - tmpArray = (int *) malloc (qty * sizeof (int)); - mergesortInPlace (numbers, tmpArray, qty); - free (tmpArray); -} - -/******************************** - * END OF PAUL'S IMPLEMENTATION * - ********************************/ - -/************************************************* - *** Implementation 1: faster on sorted arrays *** - *************************************************/ - -#define rstype_t unsigned -#define rskey(x) (x) - -#define RS_MIN_SIZE 64 - -typedef struct { - rstype_t *b, *e; -} rsbucket_t; - -void rs_sort(rstype_t *beg, rstype_t *end, int n_bits, int s) -{ - rstype_t *i; - int size = 1<<n_bits, m = size - 1; - rsbucket_t *k, b[size], *be = b + size; - - for (k = b; k != be; ++k) k->b = k->e = beg; - for (i = beg; i != end; ++i) ++b[rskey(*i)>>s&m].e; - for (k = b + 1; k != be; ++k) - k->e += (k-1)->e - beg, k->b = (k-1)->e; - for (k = b; k != be;) { - if (k->b != k->e) { - rsbucket_t *l; - if ((l = b + (rskey(*k->b)>>s&m)) != k) { - rstype_t tmp = *k->b, swap; - do { - swap = tmp; tmp = *l->b; *l->b++ = swap; - l = b + (rskey(tmp)>>s&m); - } while (l != k); - *k->b++ = tmp; - } else ++k->b; - } else ++k; - } - for (b->b = beg, k = b + 1; k != be; ++k) k->b = (k-1)->e; - if (s) { - s = s > n_bits? s - n_bits : 0; - for (k = b; k != be; ++k) - if (k->e - k->b > RS_MIN_SIZE) rs_sort(k->b, k->e, n_bits, s); - else if (k->e - k->b > 1) - for (i = k->b + 1; i < k->e; ++i) - if (rskey(*i) < rskey(*(i - 1))) { - rstype_t *j, tmp = *i; - for (j = i; j > k->b && rskey(tmp) < rskey(*(j-1)); --j) - *j = *(j - 1); - *j = tmp; - } - } -} - -/************************************************* - *** Implementation 2: faster on random arrays *** - *************************************************/ - -static inline void rs_insertsort(rstype_t *s, rstype_t *t) -{ - rstype_t *i; - for (i = s + 1; i < t; ++i) { - if (rskey(*i) < rskey(*(i - 1))) { - rstype_t *j, tmp = *i; - for (j = i; j > s && rskey(tmp) < rskey(*(j-1)); --j) - *j = *(j - 1); - *j = tmp; - } - } -} -/* -void rs_sort2(rstype_t *beg, rstype_t *end, int n_bits, int s) -{ - int j, size = 1<<n_bits, m = size - 1; - unsigned long c[size]; - rstype_t *i, *b[size], *e[size]; - - for (j = 0; j < size; ++j) c[j] = 0; - for (i = beg; i != end; ++i) ++c[rskey(*i)>>s&m]; - b[0] = e[0] = beg; - for (j = 1; j != size; ++j) b[j] = e[j] = b[j - 1] + c[j - 1]; - for (i = beg, j = 0; i != end;) { - rstype_t tmp = *i, swap; - int x; - for (;;) { - x = rskey(tmp)>>s&m; - if (e[x] == i) break; - swap = tmp; tmp = *e[x]; *e[x]++ = swap; - } - *i++ = tmp; - ++e[x]; - while (j != size && i >= b[j]) ++j; - while (j != size && e[j-1] == b[j]) ++j; - if (i < e[j-1]) i = e[j-1]; - } - if (s) { - s = s > n_bits? s - n_bits : 0; - for (j = 0; j < size; ++j) { - if (c[j] >= RS_MIN_SIZE) rs_sort2(b[j], e[j], n_bits, s); - else if (c[j] >= 2) rs_insertsort(b[j], e[j]); - } - } -} -*/ -void radix_sort(unsigned *array, int offset, int end, int shift) { - int x, y, value, temp; - int last[256] = { 0 }, pointer[256]; - - for (x=offset; x<end; ++x) { - ++last[(array[x] >> shift) & 0xFF]; - } - - last[0] += offset; - pointer[0] = offset; - for (x=1; x<256; ++x) { - pointer[x] = last[x-1]; - last[x] += last[x-1]; - } - - for (x=0; x<256; ++x) { - while (pointer[x] != last[x]) { - value = array[pointer[x]]; - y = (value >> shift) & 0xFF; - while (x != y) { - temp = array[pointer[y]]; - array[pointer[y]++] = value; - value = temp; - y = (value >> shift) & 0xFF; - } - array[pointer[x]++] = value; - } - } - - if (shift > 0) { - shift -= 8; - for (x=0; x<256; ++x) { - temp = x > 0 ? pointer[x] - pointer[x-1] : pointer[0] - offset; - if (temp > 64) { - radix_sort(array, pointer[x] - temp, pointer[x], shift); - } else if (temp > 1) rs_insertsort(array + pointer[x] - temp, array + pointer[x]); - } - } -} -/************************* - *** END OF RADIX SORT *** - *************************/ - -template< class _Type, unsigned long PowerOfTwoRadix, unsigned long Log2ofPowerOfTwoRadix, long Threshold > -inline void _RadixSort_Unsigned_PowerOf2Radix_1( _Type* a, long last, _Type bitMask, unsigned long shiftRightAmount ) -{ - const unsigned long numberOfBins = PowerOfTwoRadix; - unsigned long count[ numberOfBins ]; - for( unsigned long i = 0; i < numberOfBins; i++ ) - count[ i ] = 0; - for ( long _current = 0; _current <= last; _current++ ) // Scan the array and count the number of times each value appears - { - unsigned long digit = (unsigned long)(( a[ _current ] & bitMask ) >> shiftRightAmount ); // extract the digit we are sorting based on - count[ digit ]++; - } - long startOfBin[ numberOfBins ], endOfBin[ numberOfBins ], nextBin; - startOfBin[ 0 ] = endOfBin[ 0 ] = nextBin = 0; - for( unsigned long i = 1; i < numberOfBins; i++ ) - startOfBin[ i ] = endOfBin[ i ] = startOfBin[ i - 1 ] + count[ i - 1 ]; - for ( long _current = 0; _current <= last; ) - { - unsigned long digit; - _Type tmp = a[ _current ]; // get the compiler to recognize that a register can be used for the loop instead of a[_current] memory location - while ( true ) { - digit = (unsigned long)(( tmp & bitMask ) >> shiftRightAmount ); // extract the digit we are sorting based on - if ( endOfBin[ digit ] == _current ) - break; - _Type tmp2; - //_swap( tmp, a[ endOfBin[ digit ] ] ); - tmp2 = a[endOfBin[digit]]; a[endOfBin[digit]] = tmp; tmp = tmp2; - endOfBin[ digit ]++; - } - a[ _current ] = tmp; - endOfBin[ digit ]++; // leave the element at its location and grow the bin - _current++; // advance the current pointer to the next element - while( _current >= startOfBin[ nextBin ] && nextBin < numberOfBins ) - nextBin++; - while( endOfBin[ nextBin - 1 ] == startOfBin[ nextBin ] && nextBin < numberOfBins ) - nextBin++; - if ( _current < endOfBin[ nextBin - 1 ] ) - _current = endOfBin[ nextBin - 1 ]; - } - bitMask >>= Log2ofPowerOfTwoRadix; - if ( bitMask != 0 ) // end recursion when all the bits have been processes - { - if ( shiftRightAmount >= Log2ofPowerOfTwoRadix ) shiftRightAmount -= Log2ofPowerOfTwoRadix; - else shiftRightAmount = 0; - for( unsigned long i = 0; i < numberOfBins; i++ ) - { - long numberOfElements = endOfBin[ i ] - startOfBin[ i ]; - if ( numberOfElements >= Threshold ) // endOfBin actually points to one beyond the bin - _RadixSort_Unsigned_PowerOf2Radix_1< _Type, PowerOfTwoRadix, Log2ofPowerOfTwoRadix, Threshold >( &a[ startOfBin[ i ]], numberOfElements - 1, bitMask, shiftRightAmount ); - else if ( numberOfElements >= 2 ) - rs_insertsort(&a[ startOfBin[ i ]], &a[ endOfBin[ i ]]); - } - } -} -inline void RadixSortInPlace_HybridUnsigned_Radix256( unsigned* a, unsigned long a_size ) -{ - if ( a_size < 2 ) return; - unsigned long bitMask = 0xFF000000; // bitMask controls how many bits we process at a time - unsigned long shiftRightAmount = 24; - if ( a_size >= 32 ) - _RadixSort_Unsigned_PowerOf2Radix_1<unsigned, 256, 8, 32>(a, a_size - 1, bitMask, shiftRightAmount ); - else - rs_insertsort(a, a + a_size); -} - -struct intcmp_t { - inline int operator() (int a, int b) const { - return a < b? -1 : a > b? 1 : 0; - } -}; - -int compare_int(int a, int b) -{ - return a < b? -1 : a > b? 1 : 0; -} -int compare(const void *a, const void *b) -{ - return *((int*)a) - *((int*)b); -} - -int main(int argc, char *argv[]) -{ - int i, N = 50000000; - int *array, *temp; - clock_t t1, t2; - if (argc == 1) fprintf(stderr, "Usage: %s [%d]\n", argv[0], N); - if (argc > 1) N = atoi(argv[1]); - temp = (int*)malloc(sizeof(int) * N); - array = (int*)malloc(sizeof(int) * N); - - srand48(11); - for (i = 0; i < N; ++i) array[i] = (int)lrand48(); - t1 = clock(); - rs_sort((unsigned*)array, (unsigned*)array + N, 8, 24); - t2 = clock(); - fprintf(stderr, "radix sort: %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); - for (i = 0; i < N-1; ++i) { - if (array[i] > array[i+1]) { - fprintf(stderr, "Bug in radix sort!\n"); - exit(1); - } - } - t1 = clock(); - rs_sort((unsigned*)array, (unsigned*)array + N, 8, 24); - t2 = clock(); - fprintf(stderr, "radix sort (sorted): %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); - - srand48(11); - for (i = 0; i < N; ++i) array[i] = (int)lrand48(); - t1 = clock(); - RadixSortInPlace_HybridUnsigned_Radix256((unsigned*)array, N); -// radix_sort((unsigned*)array, 0, N, 24); - t2 = clock(); - fprintf(stderr, "vd's radix sort: %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); - for (i = 0; i < N-1; ++i) { - if (array[i] > array[i+1]) { - fprintf(stderr, "Bug in radix sort!\n"); - exit(1); - } - } - t1 = clock(); - RadixSortInPlace_HybridUnsigned_Radix256((unsigned*)array, N); -// radix_sort((unsigned*)array, 0, N, 24); - t2 = clock(); - fprintf(stderr, "vd's radix sort (sorted): %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); - - srand48(11); - for (i = 0; i < N; ++i) array[i] = (int)lrand48(); - t1 = clock(); - sort(array, array+N); - t2 = clock(); - fprintf(stderr, "STL introsort: %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); - t1 = clock(); - sort(array, array+N); - t2 = clock(); - fprintf(stderr, "STL introsort (sorted): %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); - - srand48(11); - for (i = 0; i < N; ++i) array[i] = (int)lrand48(); - t1 = clock(); - stable_sort(array, array+N); - t2 = clock(); - fprintf(stderr, "STL stablesort: %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); - t1 = clock(); - stable_sort(array, array+N); - t2 = clock(); - fprintf(stderr, "STL stablesort (sorted): %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); - - srand48(11); - for (i = 0; i < N; ++i) array[i] = (int)lrand48(); - t1 = clock(); - make_heap(array, array+N); - sort_heap(array, array+N); - t2 = clock(); - fprintf(stderr, "STL heapsort: %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); - for (i = 0; i < N-1; ++i) { - if (array[i] > array[i+1]) { - fprintf(stderr, "Bug in heap_sort!\n"); - exit(1); - } - } - t1 = clock(); - make_heap(array, array+N); - sort_heap(array, array+N); - t2 = clock(); - fprintf(stderr, "STL heapsort (sorted): %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); - - srand48(11); - for (i = 0; i < N; ++i) array[i] = (int)lrand48(); - t1 = clock(); - ks_combsort(int, N, array); - t2 = clock(); - fprintf(stderr, "combsort: %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); - for (i = 0; i < N-1; ++i) { - if (array[i] > array[i+1]) { - fprintf(stderr, "Bug in combsort!\n"); - exit(1); - } - } - - srand48(11); - for (i = 0; i < N; ++i) array[i] = (int)lrand48(); - t1 = clock(); - qsort(array, N, sizeof(int), compare); - t2 = clock(); - fprintf(stderr, "libc qsort: %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); - - srand48(11); - for (i = 0; i < N; ++i) array[i] = (int)lrand48(); - t1 = clock(); - ks_introsort(int, N, array); - t2 = clock(); - fprintf(stderr, "my introsort: %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); - for (i = 0; i < N-1; ++i) { - if (array[i] > array[i+1]) { - fprintf(stderr, "Bug in intro_sort!\n"); - exit(1); - } - } - t1 = clock(); - ks_introsort(int, N, array); - t2 = clock(); - fprintf(stderr, "introsort (sorted): %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); - - srand48(11); - for (i = 0; i < N; ++i) array[i] = (int)lrand48(); - t1 = clock(); - ks_mergesort(int, N, array, 0); - t2 = clock(); - fprintf(stderr, "iterative mergesort: %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); - for (i = 0; i < N-1; ++i) { - if (array[i] > array[i+1]) { - fprintf(stderr, "Bug in merge_sort!\n"); - exit(1); - } - } - t1 = clock(); - ks_mergesort(int, N, array, 0); - t2 = clock(); - fprintf(stderr, "iterative mergesort (sorted): %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); - - srand48(11); - for (i = 0; i < N; ++i) array[i] = (int)lrand48(); - t1 = clock(); - ks_heapmake(int, N, array); - ks_heapsort(int, N, array); - t2 = clock(); - fprintf(stderr, "my heapsort: %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); - for (i = 0; i < N-1; ++i) { - if (array[i] > array[i+1]) { - fprintf(stderr, "Bug in heap_sort!\n"); - exit(1); - } - } - t1 = clock(); - ks_heapmake(int, N, array); - ks_heapsort(int, N, array); - t2 = clock(); - fprintf(stderr, "heapsort (sorted): %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); - - srand48(11); - for (i = 0; i < N; ++i) array[i] = (int)lrand48(); - t1 = clock(); - heapSort(array, N); - t2 = clock(); - fprintf(stderr, "Paul's heapsort: %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); - for (i = 0; i < N-1; ++i) { - if (array[i] > array[i+1]) { - fprintf(stderr, "Bug in intro_sort!\n"); - exit(1); - } - } - - srand48(11); - for (i = 0; i < N; ++i) array[i] = (int)lrand48(); - t1 = clock(); - quickSort(array, N); - t2 = clock(); - fprintf(stderr, "Paul's quicksort: %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); - for (i = 0; i < N-1; ++i) { - if (array[i] > array[i+1]) { - fprintf(stderr, "Bug in intro_sort!\n"); - exit(1); - } - } - - srand48(11); - for (i = 0; i < N; ++i) array[i] = (int)lrand48(); - t1 = clock(); - mergeSort(array, N); - t2 = clock(); - fprintf(stderr, "Paul's mergesort: %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC); - for (i = 0; i < N-1; ++i) { - if (array[i] > array[i+1]) { - fprintf(stderr, "Bug in intro_sort!\n"); - exit(1); - } - } - - free(array); free(temp); - return 0; -} diff --git a/web/server/h2o/libh2o/deps/klib/test/kstring_bench.c b/web/server/h2o/libh2o/deps/klib/test/kstring_bench.c deleted file mode 100644 index 82598e88c..000000000 --- a/web/server/h2o/libh2o/deps/klib/test/kstring_bench.c +++ /dev/null @@ -1,51 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <time.h> -#include "kstring.h" - -#define N 10000000 - -int main() -{ - int i; - clock_t t; - kstring_t s, s2; - srand48(11); - s.l = s.m = 0; s.s = 0; - t = clock(); - for (i = 0; i < N; ++i) { - int x = lrand48(); - s.l = 0; - kputw(x, &s); - } - fprintf(stderr, "kputw: %lf\n", (double)(clock() - t) / CLOCKS_PER_SEC); - srand48(11); - t = clock(); - for (i = 0; i < N; ++i) { - int x = lrand48(); - s.l = 0; - ksprintf(&s, "%d", x); - } - fprintf(stderr, "ksprintf: %lf\n", (double)(clock() - t) / CLOCKS_PER_SEC); - - srand48(11); - s2.l = s2.m = 0; s2.s = 0; - t = clock(); - for (i = 0; i < N; ++i) { - int x = lrand48(); - s2.l = s.l = 0; - kputw(x, &s2); - kputs(s2.s, &s); - } - fprintf(stderr, "kputw+kputs: %lf\n", (double)(clock() - t) / CLOCKS_PER_SEC); - srand48(11); - t = clock(); - for (i = 0; i < N; ++i) { - int x = lrand48(); - s2.l = s.l = 0; - kputw(x, &s2); - ksprintf(&s, "%s", s2.s); - } - fprintf(stderr, "kputw+ksprintf: %lf\n", (double)(clock() - t) / CLOCKS_PER_SEC); - return 0; -} diff --git a/web/server/h2o/libh2o/deps/klib/test/kstring_bench2.c b/web/server/h2o/libh2o/deps/klib/test/kstring_bench2.c deleted file mode 100644 index b7707a8ec..000000000 --- a/web/server/h2o/libh2o/deps/klib/test/kstring_bench2.c +++ /dev/null @@ -1,131 +0,0 @@ -#include <string.h> -#include <stdio.h> -#include <stdlib.h> -#include <time.h> -#include "kstring.h" - -#ifdef __APPLE__ -#define HAVE_STRNSTR -#endif - -#ifdef __linux__ -#define HAVE_MEMMEM -#endif - -static int str_len = 1024*1024*128; -static int pat_len = 30; -static int alphabet = 2; -static int repeat = 50; - -char *gen_data(int len, int a) -{ - char *data; - int i; - long x; - srand48(11); - data = malloc(len); - for (i = 0; i < len; ++i) - data[i] = (int)(a * drand48()) + '!'; - data[str_len - 1] = 0; - return data; -} -// http://srcvault.scali.eu.org/cgi-bin/Syntax/c/BoyerMoore.c -char *BoyerMoore( unsigned char *data, unsigned int dataLength, unsigned char *string, unsigned int strLength ) -{ - unsigned int skipTable[256], i; - unsigned char *search; - register unsigned char lastChar; - - if (strLength == 0) - return NULL; - - for (i = 0; i < 256; i++) - skipTable[i] = strLength; - search = string; - i = --strLength; - do { - skipTable[*search++] = i; - } while (i--); - lastChar = *--search; - search = data + strLength; - dataLength -= strLength+(strLength-1); - while ((int)dataLength > 0 ) { - unsigned int skip; - skip = skipTable[*search]; - search += skip; - dataLength -= skip; - skip = skipTable[*search]; - search += skip; - dataLength -= skip; - skip = skipTable[*search]; - if (*search != lastChar) { - search += skip; - dataLength -= skip; - continue; - } - i = strLength; - do { - if (i-- == 0) return search; - } while (*--search == string[i]); - search += (strLength - i + 1); - dataLength--; - } - return NULL; -} - -int main() -{ - char *data; - int i; - clock_t t; - t = clock(); - data = gen_data(str_len, alphabet); - fprintf(stderr, "Generate data in %.3f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); - { - t = clock(); srand48(1331); - for (i = 0; i < repeat; ++i) { - int y = lrand48() % (str_len - pat_len); - char *ret; - ret = kmemmem(data, str_len, data + y, pat_len, 0); -// printf("%d, %d\n", (int)(ret - data), y); - } - fprintf(stderr, "Search patterns in %.3f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); - } - if (1) { - t = clock(); srand48(1331); - for (i = 0; i < repeat; ++i) { - int y = lrand48() % (str_len - pat_len); - char *ret; - ret = BoyerMoore(data, str_len, data + y, pat_len); -// printf("%d, %d\n", (int)(ret - data), y); - } - fprintf(stderr, "Search patterns in %.3f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); - } -#ifdef HAVE_STRNSTR - if (1) { - char *tmp; - t = clock(); srand48(1331); - tmp = calloc(pat_len+1, 1); - for (i = 0; i < repeat; ++i) { - int y = lrand48() % (str_len - pat_len); - char *ret; - memcpy(tmp, data + y, pat_len); - ret = strnstr(data, tmp, str_len); - } - fprintf(stderr, "Search patterns in %.3f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); - } -#endif -#ifdef HAVE_MEMMEM - if (1) { - t = clock(); srand48(1331); - for (i = 0; i < repeat; ++i) { - int y = lrand48() % (str_len - pat_len); - char *ret; - ret = memmem(data, str_len, data + y, pat_len); -// printf("%d, %d\n", (int)(ret - data), y); - } - fprintf(stderr, "Search patterns in %.3f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); - } -#endif - return 0; -} diff --git a/web/server/h2o/libh2o/deps/klib/test/kstring_test.c b/web/server/h2o/libh2o/deps/klib/test/kstring_test.c deleted file mode 100644 index 76f9532e7..000000000 --- a/web/server/h2o/libh2o/deps/klib/test/kstring_test.c +++ /dev/null @@ -1,76 +0,0 @@ -#include <limits.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "kstring.h" - -int nfail = 0; - -void check(const char *what, const kstring_t *ks, const char *correct) -{ - if (ks->l != strlen(correct) || strcmp(ks->s, correct) != 0) { - fprintf(stderr, "%s produced \"%.*s\" (\"%s\" is correct)\tFAIL\n", what, (int)(ks->l), ks->s, correct); - nfail++; - } -} - -void test_kputw(kstring_t *ks, int n) -{ - char buf[16]; - - ks->l = 0; - kputw(n, ks); - - sprintf(buf, "%d", n); - check("kputw()", ks, buf); -} - -void test_kputl(kstring_t *ks, long n) -{ - char buf[24]; - - ks->l = 0; - kputl(n, ks); - - sprintf(buf, "%ld", n); - check("kputl()", ks, buf); -} - -int main() -{ - kstring_t ks; - - ks.l = ks.m = 0; - ks.s = NULL; - - test_kputw(&ks, 0); - test_kputw(&ks, 1); - test_kputw(&ks, 37); - test_kputw(&ks, 12345); - test_kputw(&ks, -12345); - test_kputw(&ks, INT_MAX); - test_kputw(&ks, -INT_MAX); - test_kputw(&ks, INT_MIN); - - test_kputl(&ks, 0); - test_kputl(&ks, 1); - test_kputl(&ks, 37); - test_kputl(&ks, 12345); - test_kputl(&ks, -12345); - test_kputl(&ks, INT_MAX); - test_kputl(&ks, -INT_MAX); - test_kputl(&ks, INT_MIN); - test_kputl(&ks, LONG_MAX); - test_kputl(&ks, -LONG_MAX); - test_kputl(&ks, LONG_MIN); - - free(ks.s); - - if (nfail > 0) { - fprintf(stderr, "Total failures: %d\n", nfail); - return EXIT_FAILURE; - } - - return EXIT_SUCCESS; -} diff --git a/web/server/h2o/libh2o/deps/klib/test/kthread_test.c b/web/server/h2o/libh2o/deps/klib/test/kthread_test.c deleted file mode 100644 index 1b67ed4ea..000000000 --- a/web/server/h2o/libh2o/deps/klib/test/kthread_test.c +++ /dev/null @@ -1,69 +0,0 @@ -#include <stdio.h> -#include <assert.h> -#include <stdlib.h> -#include <pthread.h> -#if HAVE_CILK -#include <cilk/cilk.h> -#include <cilk/cilk_api.h> -#endif - -typedef struct { - int max_iter, w, h; - double xmin, xmax, ymin, ymax; - int *k; -} global_t; - -static void compute(void *_g, int i, int tid) -{ - global_t *g = (global_t*)_g; - double x, x0 = g->xmin + (g->xmax - g->xmin) * (i%g->w) / g->w; - double y, y0 = g->ymin + (g->ymax - g->ymin) * (i/g->w) / g->h; - int k; - - assert(g->k[i] < 0); - x = x0, y = y0; - for (k = 0; k < g->max_iter; ++k) { - double z = x * y; - x *= x; y *= y; - if (x + y >= 4) break; - x = x - y + x0; - y = z + z + y0; - } - g->k[i] = k; -} - -void kt_for(int n_threads, int n_items, void (*func)(void*,int,int), void *data); - -int main(int argc, char *argv[]) -{ - int i, tmp, tot, type = 0, n_threads = 2; - global_t global = { 10240*100, 800, 600, -2., -1.2, -1.2, 1.2, 0 }; -// global_t global = { 10240*1, 8, 6, -2., -1.2, -1.2, 1.2, 0 }; - - if (argc > 1) { - type = argv[1][0] == 'o'? 2 : argv[1][0] == 'c'? 3 : argv[1][0] == 'n'? 1 : 0; - if (argv[1][0] >= '0' && argv[1][0] <= '9') - n_threads = atoi(argv[1]); - } else { - fprintf(stderr, "Usage: ./a.out [openmp | cilk | #threads]\n"); - } - tot = global.w * global.h; - global.k = calloc(tot, sizeof(int)); - for (i = 0; i < tot; ++i) global.k[i] = -1; - if (type == 0) { - kt_for(n_threads, tot, compute, &global); - } else if (type == 2) { - #pragma omp parallel for - for (i = 0; i < tot; ++i) - compute(&global, i, 0); - } else if (type == 3) { - #if HAVE_CILK - cilk_for (i = 0; i < tot; ++i) - compute(&global, i, 0); - #endif - } - for (i = tmp = 0; i < tot; ++i) tmp += (global.k[i] < 0); - free(global.k); - assert(tmp == 0); - return 0; -} diff --git a/web/server/h2o/libh2o/deps/klib/test/kvec_test.cc b/web/server/h2o/libh2o/deps/klib/test/kvec_test.cc deleted file mode 100644 index 1015574e4..000000000 --- a/web/server/h2o/libh2o/deps/klib/test/kvec_test.cc +++ /dev/null @@ -1,69 +0,0 @@ -#include <vector> -#include <time.h> -#include <stdio.h> -#include <stdlib.h> -#include "kvec.h" - -int main() -{ - int M = 10, N = 20000000, i, j; - clock_t t; - t = clock(); - for (i = 0; i < M; ++i) { - int *array = (int*)malloc(N * sizeof(int)); - for (j = 0; j < N; ++j) array[j] = j; - free(array); - } - printf("C array, preallocated: %.3f sec\n", - (float)(clock() - t) / CLOCKS_PER_SEC); - t = clock(); - for (i = 0; i < M; ++i) { - int *array = 0, max = 0; - for (j = 0; j < N; ++j) { - if (j == max) { - max = !max? 1 : max << 1; - array = (int*)realloc(array, sizeof(int)*max); - } - array[j] = j; - } - free(array); - } - printf("C array, dynamic: %.3f sec\n", - (float)(clock() - t) / CLOCKS_PER_SEC); - t = clock(); - for (i = 0; i < M; ++i) { - kvec_t(int) array; - kv_init(array); - kv_resize(int, array, N); - for (j = 0; j < N; ++j) kv_a(int, array, j) = j; - kv_destroy(array); - } - printf("C vector, dynamic(kv_a): %.3f sec\n", - (float)(clock() - t) / CLOCKS_PER_SEC); - t = clock(); - for (i = 0; i < M; ++i) { - kvec_t(int) array; - kv_init(array); - for (j = 0; j < N; ++j) - kv_push(int, array, j); - kv_destroy(array); - } - printf("C vector, dynamic(kv_push): %.3f sec\n", - (float)(clock() - t) / CLOCKS_PER_SEC); - t = clock(); - for (i = 0; i < M; ++i) { - std::vector<int> array; - array.reserve(N); - for (j = 0; j < N; ++j) array[j] = j; - } - printf("C++ vector, preallocated: %.3f sec\n", - (float)(clock() - t) / CLOCKS_PER_SEC); - t = clock(); - for (i = 0; i < M; ++i) { - std::vector<int> array; - for (j = 0; j < N; ++j) array.push_back(j); - } - printf("C++ vector, dynamic: %.3f sec\n", - (float)(clock() - t) / CLOCKS_PER_SEC); - return 0; -} |