LCOV - code coverage report
Current view: top level - lib - jhash.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 47 53 88.7 %
Date: 2016-09-14 01:02:56 Functions: 5 5 100.0 %
Branches: 6 11 54.5 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (c) 2008, 2009, 2010, 2012 Nicira, Inc.
       3                 :            :  *
       4                 :            :  * Licensed under the Apache License, Version 2.0 (the "License");
       5                 :            :  * you may not use this file except in compliance with the License.
       6                 :            :  * You may obtain a copy of the License at:
       7                 :            :  *
       8                 :            :  *     http://www.apache.org/licenses/LICENSE-2.0
       9                 :            :  *
      10                 :            :  * Unless required by applicable law or agreed to in writing, software
      11                 :            :  * distributed under the License is distributed on an "AS IS" BASIS,
      12                 :            :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      13                 :            :  * See the License for the specific language governing permissions and
      14                 :            :  * limitations under the License.
      15                 :            :  */
      16                 :            : 
      17                 :            : #include <config.h>
      18                 :            : #include "jhash.h"
      19                 :            : #include <string.h>
      20                 :            : #include "unaligned.h"
      21                 :            : 
      22                 :            : /* This is the public domain lookup3 hash by Bob Jenkins from
      23                 :            :  * http://burtleburtle.net/bob/c/lookup3.c, modified for style. */
      24                 :            : 
      25                 :            : static inline uint32_t
      26                 :  267426853 : jhash_rot(uint32_t x, int k)
      27                 :            : {
      28                 :  267426853 :     return (x << k) | (x >> (32 - k));
      29                 :            : }
      30                 :            : 
      31                 :            : static inline void
      32                 :    3801118 : jhash_mix(uint32_t *a, uint32_t *b, uint32_t *c)
      33                 :            : {
      34                 :    3801118 :       *a -= *c; *a ^= jhash_rot(*c,  4); *c += *b;
      35                 :    3801118 :       *b -= *a; *b ^= jhash_rot(*a,  6); *a += *c;
      36                 :    3801118 :       *c -= *b; *c ^= jhash_rot(*b,  8); *b += *a;
      37                 :    3801118 :       *a -= *c; *a ^= jhash_rot(*c, 16); *c += *b;
      38                 :    3801118 :       *b -= *a; *b ^= jhash_rot(*a, 19); *a += *c;
      39                 :    3801118 :       *c -= *b; *c ^= jhash_rot(*b,  4); *b += *a;
      40                 :    3801118 : }
      41                 :            : 
      42                 :            : static inline void
      43                 :   34945735 : jhash_final(uint32_t *a, uint32_t *b, uint32_t *c)
      44                 :            : {
      45                 :   34945735 :       *c ^= *b; *c -= jhash_rot(*b, 14);
      46                 :   34945735 :       *a ^= *c; *a -= jhash_rot(*c, 11);
      47                 :   34945735 :       *b ^= *a; *b -= jhash_rot(*a, 25);
      48                 :   34945735 :       *c ^= *b; *c -= jhash_rot(*b, 16);
      49                 :   34945735 :       *a ^= *c; *a -= jhash_rot(*c,  4);
      50                 :   34945735 :       *b ^= *a; *b -= jhash_rot(*a, 14);
      51                 :   34945735 :       *c ^= *b; *c -= jhash_rot(*b, 24);
      52                 :   34945735 : }
      53                 :            : 
      54                 :            : /* Returns the Jenkins hash of the 'n' 32-bit words at 'p', starting from
      55                 :            :  * 'basis'.  'p' must be properly aligned.
      56                 :            :  *
      57                 :            :  * Use hash_words() instead, unless you're computing a hash function whose
      58                 :            :  * value is exposed "on the wire" so we don't want to change it. */
      59                 :            : uint32_t
      60                 :      15024 : jhash_words(const uint32_t *p, size_t n, uint32_t basis)
      61                 :            : {
      62                 :            :     uint32_t a, b, c;
      63                 :            : 
      64                 :      15024 :     a = b = c = 0xdeadbeef + (((uint32_t) n) << 2) + basis;
      65                 :            : 
      66         [ -  + ]:      15024 :     while (n > 3) {
      67                 :          0 :         a += p[0];
      68                 :          0 :         b += p[1];
      69                 :          0 :         c += p[2];
      70                 :          0 :         jhash_mix(&a, &b, &c);
      71                 :          0 :         n -= 3;
      72                 :          0 :         p += 3;
      73                 :            :     }
      74                 :            : 
      75   [ +  -  +  -  :      15024 :     switch (n) {
                      - ]
      76                 :            :     case 3:
      77                 :      13968 :         c += p[2];
      78                 :            :         /* fall through */
      79                 :            :     case 2:
      80                 :      13968 :         b += p[1];
      81                 :            :         /* fall through */
      82                 :            :     case 1:
      83                 :      15024 :         a += p[0];
      84                 :      15024 :         jhash_final(&a, &b, &c);
      85                 :            :         /* fall through */
      86                 :            :     case 0:
      87                 :      15024 :         break;
      88                 :            :     }
      89                 :      15024 :     return c;
      90                 :            : }
      91                 :            : 
      92                 :            : /* Returns the Jenkins hash of the 'n' bytes at 'p', starting from 'basis'.
      93                 :            :  *
      94                 :            :  * Use hash_bytes() instead, unless you're computing a hash function whose
      95                 :            :  * value is exposed "on the wire" so we don't want to change it. */
      96                 :            : uint32_t
      97                 :   34930711 : jhash_bytes(const void *p_, size_t n, uint32_t basis)
      98                 :            : {
      99                 :   34930711 :     const uint32_t *p = p_;
     100                 :            :     uint32_t a, b, c;
     101                 :            : 
     102                 :   34930711 :     a = b = c = 0xdeadbeef + n + basis;
     103                 :            : 
     104         [ +  + ]:   38731829 :     while (n >= 12) {
     105                 :    3801118 :         a += get_unaligned_u32(p);
     106                 :    3801118 :         b += get_unaligned_u32(p + 1);
     107                 :    3801118 :         c += get_unaligned_u32(p + 2);
     108                 :    3801118 :         jhash_mix(&a, &b, &c);
     109                 :    3801118 :         n -= 12;
     110                 :    3801118 :         p += 3;
     111                 :            :     }
     112                 :            : 
     113         [ +  - ]:   34930711 :     if (n) {
     114                 :            :         uint32_t tmp[3];
     115                 :            : 
     116                 :   34930711 :         tmp[0] = tmp[1] = tmp[2] = 0;
     117                 :   34930711 :         memcpy(tmp, p, n);
     118                 :   34930711 :         a += tmp[0];
     119                 :   34930711 :         b += tmp[1];
     120                 :   34930711 :         c += tmp[2];
     121                 :   34930711 :         jhash_final(&a, &b, &c);
     122                 :            :     }
     123                 :            : 
     124                 :   34930711 :     return c;
     125                 :            : }

Generated by: LCOV version 1.12