97 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			97 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /**
 | |
|  * Copyright (c) 2021 OceanBase
 | |
|  * OceanBase CE is licensed under Mulan PubL v2.
 | |
|  * You can use this software according to the terms and conditions of the Mulan PubL v2.
 | |
|  * You may obtain a copy of Mulan PubL v2 at:
 | |
|  *          http://license.coscl.org.cn/MulanPubL-2.0
 | |
|  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 | |
|  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 | |
|  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 | |
|  * See the Mulan PubL v2 for more details.
 | |
|  */
 | |
| 
 | |
| #define __ussl_fhmix(h) ({                      \
 | |
|       (h) ^= (h) >> 23;                         \
 | |
|       (h) *= 0x2127599bf4325c37ULL;             \
 | |
|       (h) ^= (h) >> 47; })
 | |
| 
 | |
| static uint64_t ussl_fasthash64(const void *buf, size_t len, uint64_t seed)
 | |
| {
 | |
| 	const uint64_t    m = 0x880355f21e6d1965ULL;
 | |
| 	const uint64_t *pos = (const uint64_t *)buf;
 | |
| 	const uint64_t *end = pos + (len / 8);
 | |
| 	const unsigned char *pos2;
 | |
| 	uint64_t h = seed ^ (len * m);
 | |
| 	uint64_t v;
 | |
| 
 | |
| 	while (pos != end) {
 | |
| 		v  = *pos++;
 | |
| 		h ^= __ussl_fhmix(v);
 | |
| 		h *= m;
 | |
| 	}
 | |
| 
 | |
| 	pos2 = (const unsigned char*)pos;
 | |
| 	v = 0;
 | |
| 
 | |
| 	switch (len & 7) {
 | |
|     case 7: v ^= (uint64_t)pos2[6] << 48;
 | |
|       // fall through
 | |
|     case 6: v ^= (uint64_t)pos2[5] << 40;
 | |
|       // fall through
 | |
|     case 5: v ^= (uint64_t)pos2[4] << 32;
 | |
|       // fall through
 | |
|     case 4: v ^= (uint64_t)pos2[3] << 24;
 | |
|       // fall through
 | |
|     case 3: v ^= (uint64_t)pos2[2] << 16;
 | |
|       // fall through
 | |
|     case 2: v ^= (uint64_t)pos2[1] << 8;
 | |
|       // fall through
 | |
|     case 1: v ^= (uint64_t)pos2[0];
 | |
|       h ^= __ussl_fhmix(v);
 | |
|       h *= m;
 | |
| 	}
 | |
| 	return __ussl_fhmix(h);
 | |
| }
 | |
| 
 | |
| static uint64_t __ussl_ihash_calc(uint64_t k) { return ussl_fasthash64(&k, sizeof(k), 0); }
 | |
| static ussl_link_t* __ussl_ihash_locate(ussl_hash_t* map, uint64_t k) { return &map->table[__ussl_ihash_calc(k) % map->capacity]; }
 | |
| static uint64_t __ussl_ihash_key(ussl_link_t* l) { return *(uint64_t*)(l + 1); }
 | |
| static ussl_link_t* __ussl_ihash_list_search(ussl_link_t* start, uint64_t k, ussl_link_t** prev) {
 | |
|   ussl_link_t* p = start;
 | |
|   while(p->next != NULL && __ussl_ihash_key(p->next) != k) {
 | |
|     p = p->next;
 | |
|   }
 | |
|   if (NULL != prev) {
 | |
|     *prev = p;
 | |
|   }
 | |
|   return p->next;
 | |
| }
 | |
| 
 | |
| ussl_link_t* ussl_ihash_insert(ussl_hash_t* map, ussl_link_t* klink) {
 | |
|   ussl_link_t* prev = NULL;
 | |
|   uint64_t k = __ussl_ihash_key(klink);
 | |
|   if(!__ussl_ihash_list_search(__ussl_ihash_locate(map, k), k, &prev)) {
 | |
|     ussl_link_insert(prev, klink);
 | |
|   } else {
 | |
|     klink = NULL;
 | |
|   }
 | |
|   return klink;
 | |
| }
 | |
| 
 | |
| ussl_link_t* ussl_ihash_del(ussl_hash_t* map, uint64_t k) {
 | |
|   ussl_link_t* ret = NULL;
 | |
|   ussl_link_t* prev = NULL;
 | |
|   if((ret = __ussl_ihash_list_search(__ussl_ihash_locate(map, k), k, &prev))) {
 | |
|     ussl_link_delete(prev);
 | |
|   }
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| ussl_link_t* ussl_ihash_get(ussl_hash_t* map, uint64_t k) {
 | |
|   return __ussl_ihash_list_search(__ussl_ihash_locate(map, k), k, NULL);
 | |
| }
 | |
| 
 | |
| void ussl_hash_init(ussl_hash_t* h, int64_t capacity) {
 | |
|   h->capacity = capacity;
 | |
|   memset(&h->table, 0, sizeof(ussl_link_t) * capacity);
 | |
| } | 
