1 /* 2 * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 #include "address_handler.h" 16 namespace { 17 constexpr uint64_t BITPOOL_SIZE_FIRST = 1000 * 1024; 18 constexpr uint64_t BITPOOL_SIZE_SECOND = 200 * 1024; 19 constexpr uint64_t BITPOOL_SIZE_TOTAL_ADDR = 1000 * 1024; 20 constexpr uint64_t FIRST_HASH = 16; 21 constexpr uint64_t SECOND_HASH = 13; 22 constexpr uint64_t DIVIDE_VAL = 64; 23 constexpr uint64_t SHIFT_VAL = 16; 24 constexpr uint64_t SPIN_SHIFT_FIRST = 30; 25 constexpr uint64_t SPIN_SHIFT_SECOND = 27; 26 constexpr uint64_t SPIN_SHIFT_THIRD = 31; 27 constexpr uint64_t SPIN_FIRST_SALT = 0x9e3779b97f4a7c15; 28 constexpr uint64_t SPIN_SECOND_SALT = 0xbf58476d1ce4e5b9; 29 constexpr uint64_t SPIN_THIRD_SALT = 0x94d049bb133111eb; 30 constexpr uint32_t FNV_HASH = 16777619u; 31 constexpr uint32_t MUR_FIRST_SALT = 0x85ebca6b; 32 constexpr uint32_t MUR_SECOND_SALT = 0xc2b2ae35; 33 } 34 AddressHandler(uint64_t poolSize)35AddressHandler::AddressHandler(uint64_t poolSize) 36 { 37 bitPoolSize_ = poolSize; 38 addressChecker_ = new Bitpool [poolSize] {{0}}; 39 } 40 ~AddressHandler()41AddressHandler::~AddressHandler() 42 { 43 delete [] addressChecker_; 44 addressChecker_ = nullptr; 45 successor_ = nullptr; 46 } 47 LowAddrHandler()48LowAddrHandler::LowAddrHandler() : AddressHandler(BITPOOL_SIZE_FIRST) {}; 49 AddAllocAddr(uint64_t addr)50void LowAddrHandler::AddAllocAddr(uint64_t addr) 51 { 52 if (!addressChecker_) { 53 return; 54 } 55 uint32_t addrKey = static_cast<uint32_t>(addr); 56 uint32_t val = HashFunc(addrKey) % (bitPoolSize_ * DIVIDE_VAL); 57 addressChecker_[val / DIVIDE_VAL].slot |= (0x1 << (val % DIVIDE_VAL)); 58 if (successor_ != nullptr) { 59 successor_->AddAllocAddr(addr); 60 } 61 } 62 CheckAddr(uint64_t addr)63bool LowAddrHandler::CheckAddr(uint64_t addr) 64 { 65 if (!addressChecker_) { 66 return true; 67 } 68 uint32_t addrKey = static_cast<uint32_t>(addr); 69 uint32_t val = HashFunc(addrKey) % (bitPoolSize_ * DIVIDE_VAL); 70 if (!(addressChecker_[val / DIVIDE_VAL].slot.load() & (0x1 << (val % DIVIDE_VAL)))) { 71 return false; 72 } 73 if (successor_ != nullptr) { 74 return successor_->CheckAddr(addr); 75 } 76 return true; 77 } 78 HashFunc(uint32_t addrKey)79uint32_t LowAddrHandler::HashFunc(uint32_t addrKey) 80 { 81 addrKey ^= addrKey >> FIRST_HASH; 82 addrKey *= MUR_FIRST_SALT; 83 addrKey ^= addrKey >> SECOND_HASH; 84 addrKey *= MUR_SECOND_SALT; 85 addrKey ^= addrKey >> FIRST_HASH; 86 return addrKey; 87 } 88 MidAddrHandler()89MidAddrHandler::MidAddrHandler() : AddressHandler(BITPOOL_SIZE_SECOND) {}; 90 AddAllocAddr(uint64_t addr)91void MidAddrHandler::AddAllocAddr(uint64_t addr) 92 { 93 if (!addressChecker_) { 94 return; 95 } 96 uint32_t addrKey = static_cast<uint32_t>(addr >> SHIFT_VAL); 97 uint32_t val = HashFunc(addrKey) % (bitPoolSize_ * DIVIDE_VAL); 98 addressChecker_[val / DIVIDE_VAL].slot |= (0x1 << (val % DIVIDE_VAL)); 99 if (successor_ != nullptr) { 100 successor_->AddAllocAddr(addr); 101 } 102 } 103 CheckAddr(uint64_t addr)104bool MidAddrHandler::CheckAddr(uint64_t addr) 105 { 106 if (!addressChecker_) { 107 return true; 108 } 109 uint32_t addrKey = static_cast<uint32_t>(addr >> SHIFT_VAL); 110 uint32_t val = HashFunc(addrKey) % (bitPoolSize_ * DIVIDE_VAL); 111 if (!(addressChecker_[val / DIVIDE_VAL].slot.load() & (0x1 << (val % DIVIDE_VAL)))) { 112 return false; 113 } 114 if (successor_ != nullptr) { 115 return successor_->CheckAddr(addr); 116 } 117 return true; 118 } 119 HashFunc(uint32_t addrKey)120uint32_t MidAddrHandler::HashFunc(uint32_t addrKey) 121 { 122 uint32_t hash = 2166136261u; 123 //mix in the input 124 hash ^= addrKey; 125 hash *= FNV_HASH; 126 return hash; 127 } 128 WholeAddrHandler()129WholeAddrHandler::WholeAddrHandler() : AddressHandler(BITPOOL_SIZE_TOTAL_ADDR) {}; 130 AddAllocAddr(uint64_t addr)131void WholeAddrHandler::AddAllocAddr(uint64_t addr) 132 { 133 if (!addressChecker_) { 134 return; 135 } 136 uint32_t val = HashFunc(addr) % (bitPoolSize_ * DIVIDE_VAL); 137 addressChecker_[val / DIVIDE_VAL].slot |= (0x1 << (val % DIVIDE_VAL)); 138 if (successor_ != nullptr) { 139 successor_->AddAllocAddr(addr); 140 } 141 } 142 CheckAddr(uint64_t addr)143bool WholeAddrHandler::CheckAddr(uint64_t addr) 144 { 145 if (!addressChecker_) { 146 return true; 147 } 148 uint32_t val = HashFunc(addr) % (bitPoolSize_ * DIVIDE_VAL); 149 if (!(addressChecker_[val / DIVIDE_VAL].slot.load() & (0x1 << (val % DIVIDE_VAL)))) { 150 return false; 151 } 152 if (successor_ != nullptr) { 153 return successor_->CheckAddr(addr); 154 } 155 return true; 156 } 157 HashFunc(uint64_t addrKey)158uint64_t WholeAddrHandler::HashFunc(uint64_t addrKey) 159 { 160 uint64_t hashval = (addrKey += SPIN_FIRST_SALT); 161 hashval = (hashval ^ (hashval >> SPIN_SHIFT_FIRST)) * SPIN_SECOND_SALT; 162 hashval = (hashval ^ (hashval >> SPIN_SHIFT_SECOND)) * SPIN_THIRD_SALT; 163 return hashval ^ (hashval >> SPIN_SHIFT_THIRD); 164 }