码迷,mamicode.com
首页 > 其他好文 > 详细

pike实现

时间:2015-12-29 16:05:35      阅读:203      评论:0      收藏:0      [点我收藏+]

标签:

 

稍微读了一下源码,记录一些我认为有必要的东西,只是为了以防老年痴呆!由于整体的源码还没有看得很清楚,所以大量的错误是允许的,此篇笔记也会一直处于 查询-修改 的迭代过程。

 

首先拿mapping开刀

  mapping其实就是C++中的multimap,但是支持更多。

  array values(mapping)。这个方法可以返回所有mapping中的value,那么values()究竟作了什么呢?源码中是这样定义的:

 1 PMOD_EXPORT struct array *mapping_values(struct mapping *m)
 2 {
 3   INT32 e;
 4   struct keypair *k;
 5   struct array *a;
 6   struct svalue *s;
 7 
 8 #ifdef PIKE_DEBUG
 9   if(m->data->refs <=0)
10     Pike_fatal("Zero refs in mapping->data\n");
11 #endif
12 
13   check_mapping_for_destruct(m);
14 
15   a=allocate_array(m->data->size);
16   s=ITEM(a);
17 
18   /* no locking required */
19   NEW_MAPPING_LOOP(m->data) assign_svalue(s++, & k->val);
20 
21   a->type_field = m->data->val_types;
22 
23 #ifdef PIKE_DEBUG
24   if(d_flag > 1) check_mapping_type_fields(m);
25 #endif
26   
27   return a;
28 }

  可以看到,在第15行直接申请了足够存储所有value的内存大小,第19行是一个宏,其循环了所有的可能的value,然后assign_svalue就会将每个k->value给拷贝到返回值array中,并且在27行返回a。

 

  mapping也可以将字符串作为key的,但是它是如何依靠一个ke=string来迅速地找到对应的value的呢?其实mapping使用的siphash(维基百科原著论文)来哈希字符串的,也就是先将字符串哈希成一个值,再跟其他的key的哈希值来匹配,这样就容易找到了。如果有兴趣可以看pike中的实现:

技术分享
 1 static size_t low_hashmem_siphash24( const void *s, size_t len, size_t nbytes, size_t key )
 2 {
 3   const unsigned char * in = (const unsigned char*)s;
 4   unsigned long long inlen = MINIMUM(len, nbytes);
 5 
 6   /* "some pseudo randomly generated bytes" 伪随机产生的字节 */
 7   unsigned INT64 v0 = 0x736f6d6570736575ULL;
 8   unsigned INT64 v1 = 0x646f72616e646f6dULL;
 9   unsigned INT64 v2 = 0x6c7967656e657261ULL;
10   unsigned INT64 v3 = 0x7465646279746573ULL;
11   unsigned INT64 b;
12   unsigned INT64 k0 = (unsigned INT64)key;
13   unsigned INT64 k1 = (unsigned INT64)key;
14   unsigned INT64 m;
15   const unsigned char *end = in + inlen - ( inlen % sizeof( unsigned INT64 ) );
16   const int left = inlen & 7;
17   b = ( ( unsigned INT64 )inlen ) << 56;
18   v3 ^= k1;
19   v2 ^= k0;
20   v1 ^= k1;
21   v0 ^= k0;
22 
23   for ( ; in != end; in += 8 )
24   {
25     m = U8TO64_LE( in );
26     v3 ^= m;
27     SIPROUND;
28     SIPROUND;
29     v0 ^= m;
30   }
31 
32   switch( left )
33   {
34   case 7: b |= ( ( unsigned INT64 )in[ 6] )  << 48;
35 
36   case 6: b |= ( ( unsigned INT64 )in[ 5] )  << 40;
37 
38   case 5: b |= ( ( unsigned INT64 )in[ 4] )  << 32;
39 
40   case 4: b |= ( ( unsigned INT64 )in[ 3] )  << 24;
41 
42   case 3: b |= ( ( unsigned INT64 )in[ 2] )  << 16;
43 
44   case 2: b |= ( ( unsigned INT64 )in[ 1] )  <<  8;
45 
46   case 1: b |= ( ( unsigned INT64 )in[ 0] ); break;
47 
48   case 0: break;
49   }
50 
51   v3 ^= b;
52   SIPROUND;
53   SIPROUND;
54   v0 ^= b;
55   v2 ^= 0xff;
56   SIPROUND;
57   SIPROUND;
58   SIPROUND;
59   SIPROUND;
60   b = v0 ^ v1 ^ v2  ^ v3;
61   return (size_t)b;
62 }
low_hashmen_siphash24

 

pike实现

标签:

原文地址:http://www.cnblogs.com/xcw0754/p/5085806.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!