github.com/cloudwego/dynamicgo@v0.2.6-0.20240519101509-707f41b6b834/native/map.c (about) 1 /** 2 * Copyright 2023 CloudWeGo Authors. 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 "native.h" 18 #include "memops.h" 19 #include "map.h" 20 #include "test/xprintf.h" 21 22 uint32_t hash_DJB32(const GoString str) 23 { 24 uint32_t hash = 5381ul; 25 for (int i = 0; i < str.len; i++) 26 { 27 hash = ((hash << 5) + hash + (uint32_t)str.buf[i]); 28 } 29 return hash; 30 } 31 32 void *hm_get(const HashMap *self, const GoString *key) 33 { 34 uint32_t h = hash_DJB32(*key); 35 uint32_t p = h % self->N; 36 Entry s = self->b[p]; 37 38 while (s.hash != 0) 39 { 40 if (s.hash == h && s.key.len == key->len && memeq(key->buf, s.key.buf, key->len)) 41 { 42 // xprintf("s.key:%s, s.val:%x\n", s.key.buf, s.val); 43 return s.val; 44 } 45 else 46 { 47 p = (p + 1) % self->N; 48 s = self->b[p]; 49 } 50 } 51 return NULL; 52 } 53 54 void hm_set(HashMap *self, const GoString *key, void *val) 55 { 56 uint32_t h = hash_DJB32(*key); 57 uint32_t p = h % self->N; 58 Entry *s = &self->b[p]; 59 60 while (s->hash != 0) 61 { 62 p = (p + 1) % self->N; 63 s = &self->b[p]; 64 } 65 66 // xprintf("h:%d, p:%d, key:%s, val:%x\n", h, p, key, val); 67 s->val = val; 68 s->hash = h; 69 s->key = *key; 70 self->c++; 71 } 72 73 const size_t SIZE_SIZE_T = sizeof(size_t); 74 const size_t SIZE_TRIE_NODE = sizeof(TrieNode); 75 const size_t SIZE_PAIR = sizeof(Pair); 76 77 uint8_t ascii2int(const unsigned char c) 78 { 79 if (c < CHAR_POINT) 80 { 81 return (uint8_t)(255 + c - CHAR_POINT); 82 } 83 return (uint8_t)(c - CHAR_POINT); 84 } 85 86 void *trie_get(const TrieTree *self, const GoString *key) 87 { 88 // xprintf("[trie_get] key:%s\n", key); 89 if (key->len == 0) 90 { 91 return self->empty; 92 } 93 94 size_t l = key->len - 1; 95 GoSlice fs = self->node.index; 96 GoSlice ls = *self->node.leaves; 97 98 for (int s = 0; s < self->positions.len; s++) 99 { 100 size_t i = *(size_t *)(self->positions.buf + s * SIZE_SIZE_T); 101 // xprintf("[trie_get] l:%d, position:%d\n", l, i); 102 if (i > l) 103 { 104 i = l; 105 } 106 uint8_t j = ascii2int(key->buf[i]); 107 if (j > fs.len) 108 { 109 return NULL; 110 } 111 // xprintf("[trie_get] j:%d, fs.len:%d\n", j, fs.len); 112 TrieNode *fp = (TrieNode *)(fs.buf + j * SIZE_TRIE_NODE); 113 if (fp->leaves == NULL) 114 { 115 return NULL; 116 } 117 fs = fp->index; 118 ls = *fp->leaves; 119 // xprintf("[trie_get] fp->leaves[0]:%s\n", &((Pair *)(ls.buf))->key); 120 } 121 // xprintf("[trie_get] ls.len:%d\n", l, ls.len); 122 123 for (int i = 0; i < ls.len; i++) 124 { 125 Pair *v = (Pair *)(ls.buf + i * SIZE_PAIR); 126 if (key->len == v->key.len && memeq(key->buf, v->key.buf, key->len)) 127 { 128 return v->val; 129 } 130 } 131 return NULL; 132 } 133 134 bool bm_is_set(ReqBitMap b, tid id) 135 { 136 uint64_t v = b.buf[id / BSIZE_INT64]; 137 return (v & (1ull << (id % BSIZE_INT64))) != 0; 138 } 139 140 void bm_set_req(ReqBitMap b, tid id, req_em req) 141 { 142 uint64_t *p = &b.buf[id / BSIZE_INT64]; 143 switch (req) 144 { 145 case REQ_DEFAULT: 146 case REQ_REQUIRED: 147 *p |= (uint64_t)(1ull << (id % BSIZE_INT64)); 148 break; 149 case REQ_OPTIONAL: 150 *p &= ~(uint64_t)(1ull << (id % BSIZE_INT64)); 151 break; 152 default: 153 break; 154 } 155 }