| 266 | |
| 267 | template<Cache::EvictionPolicy policy> |
| 268 | HandleBase* RLCacheShard<policy>::Allocate(Slice key, uint32_t hash, int val_len, |
| 269 | size_t charge) { |
| 270 | DCHECK(initialized_); |
| 271 | int key_len = key.size(); |
| 272 | DCHECK_GE(key_len, 0); |
| 273 | DCHECK_GE(val_len, 0); |
| 274 | DCHECK_GT(charge, 0); |
| 275 | if (charge == 0) return nullptr; |
| 276 | int key_len_padded = KUDU_ALIGN_UP(key_len, sizeof(void*)); |
| 277 | uint8_t* buf = new uint8_t[sizeof(RLHandle) |
| 278 | + key_len_padded + val_len]; // the kv_data VLA data |
| 279 | // TODO(KUDU-1091): account for the footprint of structures used by Cache's |
| 280 | // internal housekeeping (RL handles, etc.) in case of |
| 281 | // non-automatic charge. |
| 282 | int calc_charge = |
| 283 | (charge == Cache::kAutomaticCharge) ? kudu::kudu_malloc_usable_size(buf) : charge; |
| 284 | uint8_t* kv_ptr = buf + sizeof(RLHandle); |
| 285 | RLHandle* handle = new (buf) RLHandle(kv_ptr, key, hash, val_len, |
| 286 | calc_charge); |
| 287 | return handle; |
| 288 | } |
| 289 | |
| 290 | template<Cache::EvictionPolicy policy> |
| 291 | void RLCacheShard<policy>::Free(HandleBase* handle) { |