hirlite 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/LICENSE +28 -0
- data/Rakefile +51 -0
- data/ext/hirlite_ext/extconf.rb +33 -0
- data/ext/hirlite_ext/hirlite_ext.c +14 -0
- data/ext/hirlite_ext/hirlite_ext.h +38 -0
- data/ext/hirlite_ext/rlite.c +351 -0
- data/lib/hirlite/rlite.rb +1 -0
- data/lib/hirlite/version.rb +3 -0
- data/lib/hirlite.rb +2 -0
- data/vendor/rlite/Makefile +6 -0
- data/vendor/rlite/deps/crc64.c +191 -0
- data/vendor/rlite/deps/crc64.h +3 -0
- data/vendor/rlite/deps/endianconv.h +73 -0
- data/vendor/rlite/deps/hyperloglog.c +1547 -0
- data/vendor/rlite/deps/hyperloglog.h +14 -0
- data/vendor/rlite/deps/lzf.h +100 -0
- data/vendor/rlite/deps/lzfP.h +159 -0
- data/vendor/rlite/deps/lzf_c.c +295 -0
- data/vendor/rlite/deps/lzf_d.c +150 -0
- data/vendor/rlite/deps/sha1.c +227 -0
- data/vendor/rlite/deps/sha1.h +19 -0
- data/vendor/rlite/deps/utilfromredis.c +397 -0
- data/vendor/rlite/deps/utilfromredis.h +11 -0
- data/vendor/rlite/src/Makefile +79 -0
- data/vendor/rlite/src/constants.h +15 -0
- data/vendor/rlite/src/dump.c +191 -0
- data/vendor/rlite/src/dump.h +3 -0
- data/vendor/rlite/src/hirlite.c +3985 -0
- data/vendor/rlite/src/hirlite.h +186 -0
- data/vendor/rlite/src/page_btree.c +1556 -0
- data/vendor/rlite/src/page_btree.h +133 -0
- data/vendor/rlite/src/page_key.c +283 -0
- data/vendor/rlite/src/page_key.h +25 -0
- data/vendor/rlite/src/page_list.c +718 -0
- data/vendor/rlite/src/page_list.h +70 -0
- data/vendor/rlite/src/page_long.c +61 -0
- data/vendor/rlite/src/page_long.h +14 -0
- data/vendor/rlite/src/page_multi_string.c +538 -0
- data/vendor/rlite/src/page_multi_string.h +18 -0
- data/vendor/rlite/src/page_skiplist.c +689 -0
- data/vendor/rlite/src/page_skiplist.h +70 -0
- data/vendor/rlite/src/page_string.c +55 -0
- data/vendor/rlite/src/page_string.h +12 -0
- data/vendor/rlite/src/pqsort.c +185 -0
- data/vendor/rlite/src/pqsort.h +40 -0
- data/vendor/rlite/src/restore.c +401 -0
- data/vendor/rlite/src/restore.h +3 -0
- data/vendor/rlite/src/rlite.c +1309 -0
- data/vendor/rlite/src/rlite.h +159 -0
- data/vendor/rlite/src/sort.c +530 -0
- data/vendor/rlite/src/sort.h +18 -0
- data/vendor/rlite/src/status.h +19 -0
- data/vendor/rlite/src/type_hash.c +607 -0
- data/vendor/rlite/src/type_hash.h +29 -0
- data/vendor/rlite/src/type_list.c +477 -0
- data/vendor/rlite/src/type_list.h +23 -0
- data/vendor/rlite/src/type_set.c +796 -0
- data/vendor/rlite/src/type_set.h +34 -0
- data/vendor/rlite/src/type_string.c +613 -0
- data/vendor/rlite/src/type_string.h +34 -0
- data/vendor/rlite/src/type_zset.c +1147 -0
- data/vendor/rlite/src/type_zset.h +50 -0
- data/vendor/rlite/src/util.c +334 -0
- data/vendor/rlite/src/util.h +71 -0
- metadata +151 -0
@@ -0,0 +1,70 @@
|
|
1
|
+
#ifndef _RL_PAGE_SKIPLIST_H
|
2
|
+
#define _RL_PAGE_SKIPLIST_H
|
3
|
+
|
4
|
+
#include "rlite.h"
|
5
|
+
|
6
|
+
#define RL_SKIPLIST_MAXLEVEL 32
|
7
|
+
#define RL_SKIPLIST_PROBABILITY 0.25
|
8
|
+
|
9
|
+
#define RL_SKIPLIST_BEFORE_SCORE 1
|
10
|
+
#define RL_SKIPLIST_UPTO_SCORE 2
|
11
|
+
#define RL_SKIPLIST_INCLUDE_SCORE 3
|
12
|
+
#define RL_SKIPLIST_EXCLUDE_SCORE 4
|
13
|
+
|
14
|
+
struct rlite;
|
15
|
+
struct rl_data_type;
|
16
|
+
typedef struct {
|
17
|
+
long value;
|
18
|
+
double score;
|
19
|
+
long left;
|
20
|
+
long num_levels;
|
21
|
+
struct rl_skiplist_node_level {
|
22
|
+
long right;
|
23
|
+
long span;
|
24
|
+
} level[];
|
25
|
+
} rl_skiplist_node;
|
26
|
+
|
27
|
+
typedef struct {
|
28
|
+
long left;
|
29
|
+
long right;
|
30
|
+
long size;
|
31
|
+
long level;
|
32
|
+
} rl_skiplist;
|
33
|
+
|
34
|
+
typedef struct rl_skiplist_iterator {
|
35
|
+
struct rlite *db;
|
36
|
+
rl_skiplist *skiplist;
|
37
|
+
long node_page;
|
38
|
+
int direction; // 1 for right, -1 for left
|
39
|
+
int position;
|
40
|
+
long size;
|
41
|
+
} rl_skiplist_iterator;
|
42
|
+
|
43
|
+
int rl_skiplist_create(struct rlite *db, rl_skiplist **skiplist);
|
44
|
+
int rl_skiplist_destroy(struct rlite *db, void *skiplist);
|
45
|
+
int rl_skiplist_node_create(struct rlite *db, rl_skiplist_node **_node, long level, double score, long value);
|
46
|
+
int rl_skiplist_node_destroy(struct rlite *db, void *node);
|
47
|
+
int rl_skiplist_iterator_create(struct rlite *db, rl_skiplist_iterator **iterator, rl_skiplist *skiplist, long node_page, int direction, int size);
|
48
|
+
int rl_skiplist_iterator_destroy(struct rlite *db, rl_skiplist_iterator *iterator);
|
49
|
+
int rl_skiplist_iterator_next(rl_skiplist_iterator *iterator, rl_skiplist_node **node);
|
50
|
+
int rl_skiplist_add(struct rlite *db, rl_skiplist *skiplist, long skiplist_page, double score, unsigned char *value, long valuelen);
|
51
|
+
int rl_skiplist_first_node(struct rlite *db, rl_skiplist *skiplist, double score, int range_mode, unsigned char *value, long valuelen, rl_skiplist_node **node, long *rank);
|
52
|
+
int rl_skiplist_node_by_rank(struct rlite *db, rl_skiplist *skiplist, long rank, rl_skiplist_node **node, long *node_page);
|
53
|
+
int rl_skiplist_delete(struct rlite *db, rl_skiplist *skiplist, long skiplist_page, double score, unsigned char *value, long valuelen);
|
54
|
+
int rl_skiplist_delete_all(struct rlite *db, rl_skiplist *skiplist);
|
55
|
+
|
56
|
+
int rl_skiplist_is_balanced(struct rlite *db, rl_skiplist *skiplist);
|
57
|
+
#ifdef DEBUG
|
58
|
+
int rl_skiplist_print(struct rlite *db, rl_skiplist *skiplist);
|
59
|
+
#endif
|
60
|
+
|
61
|
+
int rl_skiplist_serialize(struct rlite *db, void *obj, unsigned char *data);
|
62
|
+
int rl_skiplist_deserialize(struct rlite *db, void **obj, void *context, unsigned char *data);
|
63
|
+
|
64
|
+
int rl_skiplist_node_serialize(struct rlite *db, void *obj, unsigned char *data);
|
65
|
+
int rl_skiplist_node_deserialize(struct rlite *db, void **obj, void *context, unsigned char *data);
|
66
|
+
|
67
|
+
int rl_skiplist_pages(struct rlite *db, rl_skiplist *skiplist, short *pages);
|
68
|
+
|
69
|
+
|
70
|
+
#endif
|
@@ -0,0 +1,55 @@
|
|
1
|
+
#include <stdlib.h>
|
2
|
+
#include <string.h>
|
3
|
+
#include "rlite.h"
|
4
|
+
#include "page_string.h"
|
5
|
+
#include "util.h"
|
6
|
+
|
7
|
+
int rl_string_serialize(rlite *db, void *obj, unsigned char *data)
|
8
|
+
{
|
9
|
+
memcpy(data, obj, sizeof(char) * db->page_size);
|
10
|
+
return RL_OK;
|
11
|
+
}
|
12
|
+
|
13
|
+
int rl_string_deserialize(rlite *db, void **obj, void *UNUSED(context), unsigned char *data)
|
14
|
+
{
|
15
|
+
int retval;
|
16
|
+
unsigned char *new_data;
|
17
|
+
RL_MALLOC(new_data, sizeof(char) * db->page_size);
|
18
|
+
memcpy(new_data, data, sizeof(char) * db->page_size);
|
19
|
+
*obj = new_data;
|
20
|
+
retval = RL_OK;
|
21
|
+
cleanup:
|
22
|
+
return retval;
|
23
|
+
}
|
24
|
+
|
25
|
+
int rl_string_destroy(rlite *UNUSED(db), void *obj)
|
26
|
+
{
|
27
|
+
rl_free(obj);
|
28
|
+
return RL_OK;
|
29
|
+
}
|
30
|
+
|
31
|
+
int rl_string_create(rlite *db, unsigned char **_data, long *number)
|
32
|
+
{
|
33
|
+
unsigned char *data = calloc(db->page_size, sizeof(char));
|
34
|
+
if (!data) {
|
35
|
+
return RL_OUT_OF_MEMORY;
|
36
|
+
}
|
37
|
+
*number = db->next_empty_page;
|
38
|
+
int retval;
|
39
|
+
RL_CALL(rl_write, RL_OK, db, &rl_data_type_string, db->next_empty_page, data);
|
40
|
+
*_data = data;
|
41
|
+
retval = RL_OK;
|
42
|
+
cleanup:
|
43
|
+
return retval;
|
44
|
+
}
|
45
|
+
|
46
|
+
int rl_string_get(rlite *db, unsigned char **_data, long number)
|
47
|
+
{
|
48
|
+
void *data;
|
49
|
+
int retval;
|
50
|
+
RL_CALL(rl_read, RL_FOUND, db, &rl_data_type_string, number, NULL, &data, 1);
|
51
|
+
*_data = data;
|
52
|
+
retval = RL_OK;
|
53
|
+
cleanup:
|
54
|
+
return retval;
|
55
|
+
}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
#ifndef _RL_PAGE_STRING_H
|
2
|
+
#define _RL_PAGE_STRING_H
|
3
|
+
|
4
|
+
struct rlite;
|
5
|
+
|
6
|
+
int rl_string_serialize(struct rlite *db, void *obj, unsigned char *data);
|
7
|
+
int rl_string_deserialize(struct rlite *db, void **obj, void *context, unsigned char *data);
|
8
|
+
int rl_string_destroy(struct rlite *db, void *obj);
|
9
|
+
int rl_string_create(struct rlite *db, unsigned char **data, long *number);
|
10
|
+
int rl_string_get(struct rlite *db, unsigned char **_data, long number);
|
11
|
+
|
12
|
+
#endif
|
@@ -0,0 +1,185 @@
|
|
1
|
+
/* The following is the NetBSD libc qsort implementation modified in order to
|
2
|
+
* support partial sorting of ranges for Redis.
|
3
|
+
*
|
4
|
+
* Copyright(C) 2009-2012 Salvatore Sanfilippo. All rights reserved.
|
5
|
+
*
|
6
|
+
* The original copyright notice follows. */
|
7
|
+
|
8
|
+
|
9
|
+
/* $NetBSD: qsort.c,v 1.19 2009/01/30 23:38:44 lukem Exp $ */
|
10
|
+
|
11
|
+
/*-
|
12
|
+
* Copyright (c) 1992, 1993
|
13
|
+
* The Regents of the University of California. All rights reserved.
|
14
|
+
*
|
15
|
+
* Redistribution and use in source and binary forms, with or without
|
16
|
+
* modification, are permitted provided that the following conditions
|
17
|
+
* are met:
|
18
|
+
* 1. Redistributions of source code must retain the above copyright
|
19
|
+
* notice, this list of conditions and the following disclaimer.
|
20
|
+
* 2. Redistributions in binary form must reproduce the above copyright
|
21
|
+
* notice, this list of conditions and the following disclaimer in the
|
22
|
+
* documentation and/or other materials provided with the distribution.
|
23
|
+
* 3. Neither the name of the University nor the names of its contributors
|
24
|
+
* may be used to endorse or promote products derived from this software
|
25
|
+
* without specific prior written permission.
|
26
|
+
*
|
27
|
+
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
28
|
+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
29
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
30
|
+
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
31
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
32
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
33
|
+
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
34
|
+
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
35
|
+
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
36
|
+
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
37
|
+
* SUCH DAMAGE.
|
38
|
+
*/
|
39
|
+
|
40
|
+
#include <sys/types.h>
|
41
|
+
|
42
|
+
#include <errno.h>
|
43
|
+
#include <stdlib.h>
|
44
|
+
|
45
|
+
static inline char *med3 (char *, char *, char *,
|
46
|
+
int (*)(const void *, const void *));
|
47
|
+
static inline void swapfunc (char *, char *, size_t, int);
|
48
|
+
|
49
|
+
#define min(a, b) (a) < (b) ? a : b
|
50
|
+
|
51
|
+
/*
|
52
|
+
* Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
|
53
|
+
*/
|
54
|
+
#define swapcode(TYPE, parmi, parmj, n) { \
|
55
|
+
size_t i = (n) / sizeof (TYPE); \
|
56
|
+
TYPE *pi = (TYPE *)(void *)(parmi); \
|
57
|
+
TYPE *pj = (TYPE *)(void *)(parmj); \
|
58
|
+
do { \
|
59
|
+
TYPE t = *pi; \
|
60
|
+
*pi++ = *pj; \
|
61
|
+
*pj++ = t; \
|
62
|
+
} while (--i > 0); \
|
63
|
+
}
|
64
|
+
|
65
|
+
#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
|
66
|
+
es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
|
67
|
+
|
68
|
+
static inline void
|
69
|
+
swapfunc(char *a, char *b, size_t n, int swaptype)
|
70
|
+
{
|
71
|
+
|
72
|
+
if (swaptype <= 1)
|
73
|
+
swapcode(long, a, b, n)
|
74
|
+
else
|
75
|
+
swapcode(char, a, b, n)
|
76
|
+
}
|
77
|
+
|
78
|
+
#define swap(a, b) \
|
79
|
+
if (swaptype == 0) { \
|
80
|
+
long t = *(long *)(void *)(a); \
|
81
|
+
*(long *)(void *)(a) = *(long *)(void *)(b); \
|
82
|
+
*(long *)(void *)(b) = t; \
|
83
|
+
} else \
|
84
|
+
swapfunc(a, b, es, swaptype)
|
85
|
+
|
86
|
+
#define vecswap(a, b, n) if ((n) > 0) swapfunc((a), (b), (size_t)(n), swaptype)
|
87
|
+
|
88
|
+
static inline char *
|
89
|
+
med3(char *a, char *b, char *c,
|
90
|
+
int (*cmp) (const void *, const void *))
|
91
|
+
{
|
92
|
+
|
93
|
+
return cmp(a, b) < 0 ?
|
94
|
+
(cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a ))
|
95
|
+
:(cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c ));
|
96
|
+
}
|
97
|
+
|
98
|
+
static void
|
99
|
+
_pqsort(void *a, size_t n, size_t es,
|
100
|
+
int (*cmp) (const void *, const void *), void *lrange, void *rrange)
|
101
|
+
{
|
102
|
+
char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
|
103
|
+
size_t d, r;
|
104
|
+
int swaptype, cmp_result;
|
105
|
+
|
106
|
+
loop: SWAPINIT(a, es);
|
107
|
+
if (n < 7) {
|
108
|
+
for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
|
109
|
+
for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
|
110
|
+
pl -= es)
|
111
|
+
swap(pl, pl - es);
|
112
|
+
return;
|
113
|
+
}
|
114
|
+
pm = (char *) a + (n / 2) * es;
|
115
|
+
if (n > 7) {
|
116
|
+
pl = (char *) a;
|
117
|
+
pn = (char *) a + (n - 1) * es;
|
118
|
+
if (n > 40) {
|
119
|
+
d = (n / 8) * es;
|
120
|
+
pl = med3(pl, pl + d, pl + 2 * d, cmp);
|
121
|
+
pm = med3(pm - d, pm, pm + d, cmp);
|
122
|
+
pn = med3(pn - 2 * d, pn - d, pn, cmp);
|
123
|
+
}
|
124
|
+
pm = med3(pl, pm, pn, cmp);
|
125
|
+
}
|
126
|
+
swap(a, pm);
|
127
|
+
pa = pb = (char *) a + es;
|
128
|
+
|
129
|
+
pc = pd = (char *) a + (n - 1) * es;
|
130
|
+
for (;;) {
|
131
|
+
while (pb <= pc && (cmp_result = cmp(pb, a)) <= 0) {
|
132
|
+
if (cmp_result == 0) {
|
133
|
+
swap(pa, pb);
|
134
|
+
pa += es;
|
135
|
+
}
|
136
|
+
pb += es;
|
137
|
+
}
|
138
|
+
while (pb <= pc && (cmp_result = cmp(pc, a)) >= 0) {
|
139
|
+
if (cmp_result == 0) {
|
140
|
+
swap(pc, pd);
|
141
|
+
pd -= es;
|
142
|
+
}
|
143
|
+
pc -= es;
|
144
|
+
}
|
145
|
+
if (pb > pc)
|
146
|
+
break;
|
147
|
+
swap(pb, pc);
|
148
|
+
pb += es;
|
149
|
+
pc -= es;
|
150
|
+
}
|
151
|
+
|
152
|
+
pn = (char *) a + n * es;
|
153
|
+
r = min(pa - (char *) a, pb - pa);
|
154
|
+
vecswap(a, pb - r, r);
|
155
|
+
r = min((size_t)(pd - pc), pn - pd - es);
|
156
|
+
vecswap(pb, pn - r, r);
|
157
|
+
if ((r = pb - pa) > es) {
|
158
|
+
void *_l = a, *_r = ((unsigned char*)a)+r-1;
|
159
|
+
if (!((lrange < _l && rrange < _l) ||
|
160
|
+
(lrange > _r && rrange > _r)))
|
161
|
+
_pqsort(a, r / es, es, cmp, lrange, rrange);
|
162
|
+
}
|
163
|
+
if ((r = pd - pc) > es) {
|
164
|
+
void *_l, *_r;
|
165
|
+
|
166
|
+
/* Iterate rather than recurse to save stack space */
|
167
|
+
a = pn - r;
|
168
|
+
n = r / es;
|
169
|
+
|
170
|
+
_l = a;
|
171
|
+
_r = ((unsigned char*)a)+r-1;
|
172
|
+
if (!((lrange < _l && rrange < _l) ||
|
173
|
+
(lrange > _r && rrange > _r)))
|
174
|
+
goto loop;
|
175
|
+
}
|
176
|
+
/* qsort(pn - r, r / es, es, cmp);*/
|
177
|
+
}
|
178
|
+
|
179
|
+
void
|
180
|
+
pqsort(void *a, size_t n, size_t es,
|
181
|
+
int (*cmp) (const void *, const void *), size_t lrange, size_t rrange)
|
182
|
+
{
|
183
|
+
_pqsort(a,n,es,cmp,((unsigned char*)a)+(lrange*es),
|
184
|
+
((unsigned char*)a)+((rrange+1)*es)-1);
|
185
|
+
}
|
@@ -0,0 +1,40 @@
|
|
1
|
+
/* The following is the NetBSD libc qsort implementation modified in order to
|
2
|
+
* support partial sorting of ranges for Redis.
|
3
|
+
*
|
4
|
+
* Copyright (c) 2009-2012, Salvatore Sanfilippo <antirez at gmail dot com>
|
5
|
+
* All rights reserved.
|
6
|
+
*
|
7
|
+
* Redistribution and use in source and binary forms, with or without
|
8
|
+
* modification, are permitted provided that the following conditions are met:
|
9
|
+
*
|
10
|
+
* * Redistributions of source code must retain the above copyright notice,
|
11
|
+
* this list of conditions and the following disclaimer.
|
12
|
+
* * Redistributions in binary form must reproduce the above copyright
|
13
|
+
* notice, this list of conditions and the following disclaimer in the
|
14
|
+
* documentation and/or other materials provided with the distribution.
|
15
|
+
* * Neither the name of Redis nor the names of its contributors may be used
|
16
|
+
* to endorse or promote products derived from this software without
|
17
|
+
* specific prior written permission.
|
18
|
+
*
|
19
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
20
|
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
21
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
22
|
+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
23
|
+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
24
|
+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
25
|
+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
26
|
+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
27
|
+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
28
|
+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
29
|
+
* POSSIBILITY OF SUCH DAMAGE.
|
30
|
+
*
|
31
|
+
* See the pqsort.c file for the original copyright notice. */
|
32
|
+
|
33
|
+
#ifndef __PQSORT_H
|
34
|
+
#define __PQSORT_H
|
35
|
+
|
36
|
+
void
|
37
|
+
pqsort(void *a, size_t n, size_t es,
|
38
|
+
int (*cmp) (const void *, const void *), size_t lrange, size_t rrange);
|
39
|
+
|
40
|
+
#endif
|