设为首页 收藏本站
查看: 4365|回复: 0

[经验分享] Redis源码笔记五: intset

[复制链接]

尚未签到

发表于 2015-7-22 04:28:14 | 显示全部楼层 |阅读模式
DSC0000.gif DSC0001.gif


1 /*
2  * Copyright (c) 2009-2012, Pieter Noordhuis
3  * Copyright (c) 2009-2012, Salvatore Sanfilippo
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  *   * Redistributions of source code must retain the above copyright notice,
10  *     this list of conditions and the following disclaimer.
11  *   * Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution.
14  *   * Neither the name of Redis nor the names of its contributors may be used
15  *     to endorse or promote products derived from this software without
16  *     specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #ifndef __INTSET_H
32 #define __INTSET_H
33 #include
34
35 typedef struct intset {
36
37     /*  保存元素使用的类型的长度 */
38     uint32_t encoding;
39
40     /* 元素个数 */
41     uint32_t length;
42
43     /* 保存元素的数组 */
44     int8_t contents[];
45 } intset; /* 整数集 */
46
47 /* 创建intset */
48 intset *intsetNew(void);
49
50 /* 添加新元素(不升级) */
51 intset *intsetAdd(intset *is, int64_t value, uint8_t *success);
52
53 /* 删除元素 */
54 intset *intsetRemove(intset *is, int64_t value, int *success);
55
56 uint8_t intsetFind(intset *is, int64_t value);
57
58 int64_t intsetRandom(intset *is);
59
60 /* 按索引获取元素 */
61 uint8_t intsetGet(intset *is, uint32_t pos, int64_t *value);
62
63 uint32_t intsetLen(intset *is);
64
65 size_t intsetBlobLen(intset *is);
66
67 #endif // __INTSET_H
intset.h




  1 /*
  2  * Copyright (c) 2009-2012, Pieter Noordhuis
  3  * Copyright (c) 2009-2012, Salvatore Sanfilippo
  4  * All rights reserved.
  5  *
  6  * Redistribution and use in source and binary forms, with or without
  7  * modification, are permitted provided that the following conditions are met:
  8  *
  9  *   * Redistributions of source code must retain the above copyright notice,
10  *     this list of conditions and the following disclaimer.
11  *   * Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution.
14  *   * Neither the name of Redis nor the names of its contributors may be used
15  *     to endorse or promote products derived from this software without
16  *     specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include
32 #include
33 #include
34 #include "intset.h"
35 #include "zmalloc.h"
36 #include "endianconv.h"
37
38 /* Note that these encodings are ordered, so:
39  * INTSET_ENC_INT16 < INTSET_ENC_INT32 < INTSET_ENC_INT64. */
40 #define INTSET_ENC_INT16 (sizeof(int16_t))
41 #define INTSET_ENC_INT32 (sizeof(int32_t))
42 #define INTSET_ENC_INT64 (sizeof(int64_t))
43
44 /* Return the required encoding for the provided value. */
45 /* 返回编码v所需的长度 */
46 static uint8_t _intsetValueEncoding(int64_t v) {
47     if (v < INT32_MIN || v > INT32_MAX)
48         return INTSET_ENC_INT64;
49     else if (v < INT16_MIN || v > INT16_MAX)
50         return INTSET_ENC_INT32;
51     else
52         return INTSET_ENC_INT16;
53 }
54
55 /* Return the value at pos, given an encoding. */
56 /* 根据给定编码方式,返回给定位置上的值 */
57 static int64_t _intsetGetEncoded(intset *is, int pos, uint8_t enc) {
58     int64_t v64;
59     int32_t v32;
60     int16_t v16;
61
62     if (enc == INTSET_ENC_INT64) {
63         memcpy(&v64,((int64_t*)is->contents)+pos,sizeof(v64));
64         memrev64ifbe(&v64);
65         return v64;
66     } else if (enc == INTSET_ENC_INT32) {
67         memcpy(&v32,((int32_t*)is->contents)+pos,sizeof(v32));
68         memrev32ifbe(&v32);
69         return v32;
70     } else {
71         memcpy(&v16,((int16_t*)is->contents)+pos,sizeof(v16));
72         memrev16ifbe(&v16);
73         return v16;
74     }
75 }
76
77 /* Return the value at pos, using the configured encoding. */
78 /* 返回intset上给定pos的值 */
79 static int64_t _intsetGet(intset *is, int pos) {
80     return _intsetGetEncoded(is,pos,intrev32ifbe(is->encoding));
81 }
82
83 /* Set the value at pos, using the configured encoding. */
84 /* 将intset上给定pos的值设置为value */
85 static void _intsetSet(intset *is, int pos, int64_t value) {
86     uint32_t encoding = intrev32ifbe(is->encoding);
87
88     if (encoding == INTSET_ENC_INT64) {
89         ((int64_t*)is->contents)[pos] = value;
90         memrev64ifbe(((int64_t*)is->contents)+pos);
91     } else if (encoding == INTSET_ENC_INT32) {
92         ((int32_t*)is->contents)[pos] = value;
93         memrev32ifbe(((int32_t*)is->contents)+pos);
94     } else {
95         ((int16_t*)is->contents)[pos] = value;
96         memrev16ifbe(((int16_t*)is->contents)+pos);
97     }
98 }
99
100 /* Create an empty intset. */
101 /* 创建一个空的intset */
102 intset *intsetNew(void) {
103     /* 分配内存空间 */
104     intset *is = zmalloc(sizeof(intset));
105
106     /* 更新属性 */
107     is->encoding = intrev32ifbe(INTSET_ENC_INT16);
108     is->length = 0;
109
110     return is;
111 }
112
113 /* Resize the intset */
114 /* 调整intset的大小 */
115 static intset *intsetResize(intset *is, uint32_t len) {
116     uint32_t size = len*intrev32ifbe(is->encoding);
117
118     /* 重新分配空间 */
119     is = zrealloc(is,sizeof(intset)+size);
120
121     return is;
122 }
123
124 /* Search for the position of "value". Return 1 when the value was found and
125  * sets "pos" to the position of the value within the intset. Return 0 when
126  * the value is not present in the intset and sets "pos" to the position
127  * where "value" can be inserted. */
128  /* 查找value在is中的索引
129   *
130   * 查找成功时,将索引保存到pos,并返回1;
131   * 查找失败时,返回0,并将value可以插入的索引保存到pos;
132  */
133 static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
134     int min = 0, max = intrev32ifbe(is->length)-1, mid = -1;
135     int64_t cur = -1;
136
137     /* The value can never be found when the set is empty */
138     if (intrev32ifbe(is->length) == 0) {
139         /* 当is为空时,总是查找失败 */
140         if (pos) *pos = 0;
141         return 0;
142     } else {
143         /* Check for the case where we know we cannot find the value,
144          * but do know the insert position. */
145         if (value > _intsetGet(is,intrev32ifbe(is->length)-1)) {
146             /* 值比is中的最后一个值(所有元素中的最大值)要大,那么这个值应该插入到is最后 */
147             if (pos) *pos = intrev32ifbe(is->length);
148             return 0;
149         } else if (value < _intsetGet(is,0)) {
150             /* value最为新的最小值,插入到is最前 */
151             if (pos) *pos = 0;
152             return 0;
153         }
154     }
155     
156     /* 在is元素数组中进行二分查找 */
157     while(max >= min) {
158         mid = (min+max)/2;
159         cur = _intsetGet(is,mid);
160         if (value > cur) {
161             min = mid+1;
162         } else if (value < cur) {
163             max = mid-1;
164         } else {
165             break;
166         }
167     }
168
169     if (value == cur) {
170         if (pos) *pos = mid;
171         return 1;
172     } else {
173         if (pos) *pos = min;
174         return 0;
175     }
176 }
177
178 /* Upgrades the intset to a larger encoding and inserts the given integer. */
179 /* 根据value,对intset所使用的编码方式进行升级,并扩容intset,最后将value插入到新intset中 */
180 static intset *intsetUpgradeAndAdd(intset *is, int64_t value) {
181     /* 当前值的编码类型 */
182     uint8_t curenc = intrev32ifbe(is->encoding);
183     /* 新值的编码类型 */
184     uint8_t newenc = _intsetValueEncoding(value);
185
186     /* 元素数量 */
187     int length = intrev32ifbe(is->length);
188
189     /* 决定新值插入的位置(0为头,1为尾) */
190     int prepend = value < 0 ? 1 : 0;
191
192     /* First set new encoding and resize */
193     /* 设置新编码.并根据新编码进行扩容 */
194     is->encoding = intrev32ifbe(newenc);
195     is = intsetResize(is,intrev32ifbe(is->length)+1);
196
197     /* Upgrade back-to-front so we don't overwrite values.
198      * Note that the "prepend" variable is used to make sure we have an empty
199      * space at either the beginning or the end of the intset. */
200     /* 从最后的元素开始进行重新插入
201      * 以新元素插入到最开始为例子,之前:
202      * | 1 | 2 | 3 |
203      * 之后:
204      * | 1 | 2 |                       |   3   |  重插入3
205      * | 1 |                   |   2   |   3   |  重插入2
206      * |               |   1   |   2   |   3   |  重插入1
207      * |     ????      |   1   |   2   |   3   |  ???预留给新元素的空位
208      *
209      * 注: "prepend"是为插入新值而设置的索引偏移量;
210     */
211     while(length--)
212         _intsetSet(is,length+prepend,_intsetGetEncoded(is,length,curenc));
213
214     /* Set the value at the beginning or the end. */
215     if (prepend)
216         _intsetSet(is,0,value);
217     else
218         _intsetSet(is,intrev32ifbe(is->length),value);
219
220     /* 更新is元素数量 */
221     is->length = intrev32ifbe(intrev32ifbe(is->length)+1);
222
223     return is;
224 }
225
226 /*
227  * 对从from开始,到is末尾的所有数据进行移动,以to为起点
228  *
229  * 假设索引2 为from, 索引1 为to:
230  * 之前:
231  * 索引 | 0 | 1 | 2 | 3 |
232  * 值   | a | b | c | d |
233  * 之后:
234  * 索引 | 0 | 1 | 2 | 3 |
235  * 值   | a | c | d | d |
236
237 */
238 static void intsetMoveTail(intset *is, uint32_t from, uint32_t to) {
239     void *src, *dst;
240
241     /* 需要移动的元素个数 */
242     uint32_t bytes = intrev32ifbe(is->length)-from;
243
244     /* 数组内元素的编码方式 */
245     uint32_t encoding = intrev32ifbe(is->encoding);
246
247     if (encoding == INTSET_ENC_INT64) {
248         /* 计算地址 */
249         src = (int64_t*)is->contents+from;
250         dst = (int64_t*)is->contents+to;
251
252         /* 需要移动的字节数 */
253         bytes *= sizeof(int64_t);
254     } else if (encoding == INTSET_ENC_INT32) {
255         src = (int32_t*)is->contents+from;
256         dst = (int32_t*)is->contents+to;
257         bytes *= sizeof(int32_t);
258     } else {
259         src = (int16_t*)is->contents+from;
260         dst = (int16_t*)is->contents+to;
261         bytes *= sizeof(int16_t);
262     }
263     memmove(dst,src,bytes);
264 }
265
266 /* Insert an integer in the intset */
267 /* 将value添加到集合中
268  * 如果元素已经存在, *success被设置为0;
269  * 如果元素添加成功m *success被设置为1;
270 */
271 intset *intsetAdd(intset *is, int64_t value, uint8_t *success) {
272     uint8_t valenc = _intsetValueEncoding(value);
273     uint32_t pos;
274     if (success) *success = 1;
275
276     /* Upgrade encoding if necessary. If we need to upgrade, we know that
277      * this value should be either appended (if > 0) or prepended (if < 0),
278      * because it lies outside the range of existing values. */
279     /* 如果有需要,进行升级并插入新值 */
280     if (valenc > intrev32ifbe(is->encoding)) {
281         /* This always succeeds, so we don't need to curry *success. */
282         return intsetUpgradeAndAdd(is,value);
283     } else {
284         /* Abort if the value is already present in the set.
285          * This call will populate "pos" with the right position to insert
286          * the value when it cannot be found. */
287         /* 如果值已经存在,那么直接返回 */
288         /* 如果不存在,那么设置*pos设置为新元素添加的位置 */
289         if (intsetSearch(is,value,&pos)) {
290             if (success) *success = 0;
291             return is;
292         }
293     
294         /* 扩张is,准备添加新元素 */
295         is = intsetResize(is,intrev32ifbe(is->length)+1);
296
297         /* 如果pos不是数组中最后一个元素, 那么对数组中的原有元素进行移动 */
298         if (pos < intrev32ifbe(is->length)) intsetMoveTail(is,pos,pos+1);
299     }
300     
301     /* 添加新元素 */
302     _intsetSet(is,pos,value);
303
304     /* 更新元素数量 */
305     is->length = intrev32ifbe(intrev32ifbe(is->length)+1);
306
307     return is;
308 }
309
310 /* Delete integer from intset */
311 /* 把value从inset中移除
312  *
313  * 移除成功将*success设置为1,失败则设置为0;
314 */
315 intset *intsetRemove(intset *is, int64_t value, int *success) {
316     uint8_t valenc = _intsetValueEncoding(value);
317     uint32_t pos;
318     if (success) *success = 0;
319
320     if (valenc encoding) && /* 编码方式匹配 */
321         intsetSearch(is,value,&pos))            /* 将位置保存到pos */
322     {
323         uint32_t len = intrev32ifbe(is->length);
324
325         /* We know we can delete */
326         if (success) *success = 1;
327
328         /* Overwrite value with tail and update length */
329         /* 如果pos不是is的最末尾,那么显示的删除它 */
330         /* 如果pos = (len - 1), 那么紧缩空间时值就会被自动抹除掉 */
331         if (pos < (len-1)) intsetMoveTail(is,pos+1,pos);
332
333         /* 紧缩空间, 并更新数量计数器 */
334         is = intsetResize(is,len-1);
335         is->length = intrev32ifbe(len-1);
336     }
337     return is;
338 }
339
340 /* Determine whether a value belongs to this set */
341 /* 查看value是否存在于is */
342 uint8_t intsetFind(intset *is, int64_t value) {
343     uint8_t valenc = _intsetValueEncoding(value);
344     return valenc encoding) && /* 编码方式匹配 */
345             intsetSearch(is,value,NULL); /* 查找value */
346 }
347
348 /* Return random member */
349 /* 随机返回一个intset里的元素 */
350 int64_t intsetRandom(intset *is) {
351     return _intsetGet(is,rand()%intrev32ifbe(is->length));
352 }
353
354 /* Sets the value to the value at the given position. When this position is
355  * out of range the function returns 0, when in range it returns 1. */
356 /* 将is中位置pos的值保存到*value当中,并返回1 */
357 /* 如果pos超过is的元素数量(out of range),则返回0 */
358 uint8_t intsetGet(intset *is, uint32_t pos, int64_t *value) {
359     if (pos < intrev32ifbe(is->length)) {
360         *value = _intsetGet(is,pos);
361         return 1;
362     }
363     return 0;
364 }
365
366 /* 返回intset的元素数量 */
367 /* Return intset length */
368 uint32_t intsetLen(intset *is) {
369     return intrev32ifbe(is->length);
370 }
371
372 /* Return intset blob size in bytes. */
373 /* 以字节形式返回intset占用的空间大小 */
374 size_t intsetBlobLen(intset *is) {
375     return sizeof(intset)+intrev32ifbe(is->length)*intrev32ifbe(is->encoding);
376 }
377
378 #ifdef INTSET_TEST_MAIN
379 #include
380
381 void intsetRepr(intset *is) {
382     int i;
383     for (i = 0; i < intrev32ifbe(is->length); i++) {
384         printf("%lld\n", (uint64_t)_intsetGet(is,i));
385     }
386     printf("\n");
387 }
388
389 void error(char *err) {
390     printf("%s\n", err);
391     exit(1);
392 }
393
394 void ok(void) {
395     printf("OK\n");
396 }
397
398 long long usec(void) {
399     struct timeval tv;
400     gettimeofday(&tv,NULL);
401     return (((long long)tv.tv_sec)*1000000)+tv.tv_usec;
402 }
403
404 #define assert(_e) ((_e)?(void)0:(_assert(#_e,__FILE__,__LINE__),exit(1)))
405 void _assert(char *estr, char *file, int line) {
406     printf("\n\n=== ASSERTION FAILED ===\n");
407     printf("==> %s:%d '%s' is not true\n",file,line,estr);
408 }
409
410 intset *createSet(int bits, int size) {
411     uint64_t mask = (1length)-1); i++) {
430         uint32_t encoding = intrev32ifbe(is->encoding);
431
432         if (encoding == INTSET_ENC_INT16) {
433             int16_t *i16 = (int16_t*)is->contents;
434             assert(i16 < i16[i+1]);
435         } else if (encoding == INTSET_ENC_INT32) {
436             int32_t *i32 = (int32_t*)is->contents;
437             assert(i32 < i32[i+1]);
438         } else {
439             int64_t *i64 = (int64_t*)is->contents;
440             assert(i64 < i64[i+1]);
441         }
442     }
443 }
444
445 int main(int argc, char **argv) {
446     uint8_t success;
447     int i;
448     intset *is;
449     sranddev();
450
451     printf("Value encodings: "); {
452         assert(_intsetValueEncoding(-32768) == INTSET_ENC_INT16);
453         assert(_intsetValueEncoding(+32767) == INTSET_ENC_INT16);
454         assert(_intsetValueEncoding(-32769) == INTSET_ENC_INT32);
455         assert(_intsetValueEncoding(+32768) == INTSET_ENC_INT32);
456         assert(_intsetValueEncoding(-2147483648) == INTSET_ENC_INT32);
457         assert(_intsetValueEncoding(+2147483647) == INTSET_ENC_INT32);
458         assert(_intsetValueEncoding(-2147483649) == INTSET_ENC_INT64);
459         assert(_intsetValueEncoding(+2147483648) == INTSET_ENC_INT64);
460         assert(_intsetValueEncoding(-9223372036854775808ull) == INTSET_ENC_INT64);
461         assert(_intsetValueEncoding(+9223372036854775807ull) == INTSET_ENC_INT64);
462         ok();
463     }
464
465     printf("Basic adding: "); {
466         is = intsetNew();
467         is = intsetAdd(is,5,&success); assert(success);
468         is = intsetAdd(is,6,&success); assert(success);
469         is = intsetAdd(is,4,&success); assert(success);
470         is = intsetAdd(is,4,&success); assert(!success);
471         ok();
472     }
473
474     printf("Large number of random adds: "); {
475         int inserts = 0;
476         is = intsetNew();
477         for (i = 0; i < 1024; i++) {
478             is = intsetAdd(is,rand()%0x800,&success);
479             if (success) inserts++;
480         }
481         assert(intrev32ifbe(is->length) == inserts);
482         checkConsistency(is);
483         ok();
484     }
485
486     printf("Upgrade from int16 to int32: "); {
487         is = intsetNew();
488         is = intsetAdd(is,32,NULL);
489         assert(intrev32ifbe(is->encoding) == INTSET_ENC_INT16);
490         is = intsetAdd(is,65535,NULL);
491         assert(intrev32ifbe(is->encoding) == INTSET_ENC_INT32);
492         assert(intsetFind(is,32));
493         assert(intsetFind(is,65535));
494         checkConsistency(is);
495
496         is = intsetNew();
497         is = intsetAdd(is,32,NULL);
498         assert(intrev32ifbe(is->encoding) == INTSET_ENC_INT16);
499         is = intsetAdd(is,-65535,NULL);
500         assert(intrev32ifbe(is->encoding) == INTSET_ENC_INT32);
501         assert(intsetFind(is,32));
502         assert(intsetFind(is,-65535));
503         checkConsistency(is);
504         ok();
505     }
506
507     printf("Upgrade from int16 to int64: "); {
508         is = intsetNew();
509         is = intsetAdd(is,32,NULL);
510         assert(intrev32ifbe(is->encoding) == INTSET_ENC_INT16);
511         is = intsetAdd(is,4294967295,NULL);
512         assert(intrev32ifbe(is->encoding) == INTSET_ENC_INT64);
513         assert(intsetFind(is,32));
514         assert(intsetFind(is,4294967295));
515         checkConsistency(is);
516
517         is = intsetNew();
518         is = intsetAdd(is,32,NULL);
519         assert(intrev32ifbe(is->encoding) == INTSET_ENC_INT16);
520         is = intsetAdd(is,-4294967295,NULL);
521         assert(intrev32ifbe(is->encoding) == INTSET_ENC_INT64);
522         assert(intsetFind(is,32));
523         assert(intsetFind(is,-4294967295));
524         checkConsistency(is);
525         ok();
526     }
527
528     printf("Upgrade from int32 to int64: "); {
529         is = intsetNew();
530         is = intsetAdd(is,65535,NULL);
531         assert(intrev32ifbe(is->encoding) == INTSET_ENC_INT32);
532         is = intsetAdd(is,4294967295,NULL);
533         assert(intrev32ifbe(is->encoding) == INTSET_ENC_INT64);
534         assert(intsetFind(is,65535));
535         assert(intsetFind(is,4294967295));
536         checkConsistency(is);
537
538         is = intsetNew();
539         is = intsetAdd(is,65535,NULL);
540         assert(intrev32ifbe(is->encoding) == INTSET_ENC_INT32);
541         is = intsetAdd(is,-4294967295,NULL);
542         assert(intrev32ifbe(is->encoding) == INTSET_ENC_INT64);
543         assert(intsetFind(is,65535));
544         assert(intsetFind(is,-4294967295));
545         checkConsistency(is);
546         ok();
547     }
548
549     printf("Stress lookups: "); {
550         long num = 100000, size = 10000;
551         int i, bits = 20;
552         long long start;
553         is = createSet(bits,size);
554         checkConsistency(is);
555
556         start = usec();
557         for (i = 0; i < num; i++) intsetSearch(is,rand() % ((1

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-89179-1-1.html 上篇帖子: redis windows version 下篇帖子: Redis事件驱动库<转>
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表