github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/cpvmm/vmm/utils/hash64.c (about) 1 /* 2 * Copyright (c) 2013 Intel Corporation 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 * http://www.apache.org/licenses/LICENSE-2.0 8 * Unless required by applicable law or agreed to in writing, software 9 * distributed under the License is distributed on an "AS IS" BASIS, 10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 * See the License for the specific language governing permissions and 12 * limitations under the License. 13 */ 14 15 #include <vmm_defs.h> 16 #include <heap.h> 17 #include <hash64_api.h> 18 #include <common_libc.h> 19 #include <vmm_dbg.h> 20 #include "hash64.h" 21 #include "file_codes.h" 22 23 #define VMM_DEADLOOP() VMM_DEADLOOP_LOG(HASH64_C) 24 #define VMM_ASSERT(__condition) VMM_ASSERT_LOG(HASH64_C, __condition) 25 26 INLINE void* hash64_uint64_to_ptr(UINT64 value) { 27 return (void*)(value); 28 } 29 30 INLINE UINT64 hash64_ptr_to_uint64(void* ptr) { 31 return (UINT64)ptr; 32 } 33 34 INLINE void* hash64_allocate_node(HASH64_TABLE* hash) { 35 HASH64_NODE_ALLOCATION_FUNC node_alloc_func = hash64_get_node_alloc_func(hash); 36 void* context = hash64_get_allocation_deallocation_context(hash); 37 38 return node_alloc_func(context); 39 } 40 41 INLINE void hash64_free_node(HASH64_TABLE* hash, void* data) { 42 HASH64_NODE_DEALLOCATION_FUNC node_dealloc_func = hash64_get_node_dealloc_func(hash); 43 void* context = hash64_get_allocation_deallocation_context(hash); 44 45 node_dealloc_func(context, data); 46 } 47 48 INLINE void* hash64_mem_alloc(HASH64_TABLE* hash, UINT32 size) { 49 HASH64_INTERNAL_MEM_ALLOCATION_FUNC mem_alloc_func = hash64_get_mem_alloc_func(hash); 50 if (mem_alloc_func == NULL) { 51 return vmm_memory_alloc(size); 52 } 53 else { 54 return mem_alloc_func(size); 55 } 56 } 57 58 INLINE void hash64_mem_free(HASH64_TABLE* hash, void* data) { 59 HASH64_INTERNAL_MEM_DEALLOCATION_FUNC mem_dealloc_func = hash64_get_mem_dealloc_func(hash); 60 if (mem_dealloc_func == NULL) { 61 vmm_memory_free(data); 62 } 63 else { 64 mem_dealloc_func(data); 65 } 66 } 67 68 static HASH64_NODE** hash64_retrieve_appropriate_array_cell( 69 HASH64_TABLE* hash, UINT64 key) { 70 HASH64_FUNC hash_func; 71 UINT32 cell_index; 72 HASH64_NODE** array; 73 74 hash_func = hash64_get_hash_func(hash); 75 cell_index = hash_func(key, hash64_get_hash_size(hash)); 76 array = hash64_get_array(hash); 77 return &(array[cell_index]); 78 } 79 80 static HASH64_NODE* hash64_find(HASH64_TABLE* hash, 81 UINT64 key) { 82 HASH64_NODE** cell; 83 HASH64_NODE* node; 84 85 cell = hash64_retrieve_appropriate_array_cell(hash, key); 86 node = *cell; 87 88 while (node != NULL) { 89 if (hash64_node_get_key(node) == key) { 90 break; 91 } 92 node = hash64_node_get_next(node); 93 } 94 return node; 95 } 96 97 static BOOLEAN hash64_insert_internal(HASH64_TABLE* hash, 98 UINT64 key, UINT64 value, BOOLEAN update_when_found) { 99 HASH64_NODE* node = NULL; 100 101 if (update_when_found) { 102 node = hash64_find(hash, key); 103 } 104 else { 105 // The key should not exist 106 // BEFORE_VMLAUNCH. CRITICAL check that should not fail. 107 VMM_ASSERT(hash64_find(hash, key) == NULL); 108 } 109 110 if (node == NULL) { 111 HASH64_NODE** cell; 112 113 node = hash64_allocate_node(hash); 114 if (node == NULL) { 115 return FALSE; 116 } 117 cell = hash64_retrieve_appropriate_array_cell(hash, key); 118 119 hash64_node_set_next(node, *cell); 120 *cell = node; 121 122 hash64_node_set_key(node, key); 123 124 hash64_inc_element_count(hash); 125 } 126 else { 127 // BEFORE_VMLAUNCH. CRITICAL check that should not fail. 128 VMM_ASSERT(hash64_node_get_key(node) == key); 129 } 130 hash64_node_set_value(node, value); 131 VMM_ASSERT(hash64_find(hash, key) != NULL); 132 return TRUE; 133 } 134 135 static HASH64_HANDLE hash64_create_hash_internal( 136 HASH64_FUNC hash_func, 137 HASH64_INTERNAL_MEM_ALLOCATION_FUNC mem_alloc_func, 138 HASH64_INTERNAL_MEM_DEALLOCATION_FUNC mem_dealloc_func, 139 HASH64_NODE_ALLOCATION_FUNC node_alloc_func, 140 HASH64_NODE_DEALLOCATION_FUNC node_dealloc_func, 141 void* node_allocation_deallocation_context, 142 UINT32 hash_size, BOOLEAN is_multiple_values_hash) { 143 HASH64_TABLE* hash; 144 HASH64_NODE** array; 145 UINT32 index; 146 147 if (mem_alloc_func == NULL) { 148 hash = (HASH64_TABLE*)vmm_memory_alloc(sizeof(HASH64_TABLE)); 149 } 150 else { 151 hash = (HASH64_TABLE*)mem_alloc_func(sizeof(HASH64_TABLE)); 152 } 153 154 if (hash == NULL) { 155 goto hash_allocation_failed; 156 } 157 158 if (mem_alloc_func == NULL) { 159 array = (HASH64_NODE**)vmm_memory_alloc(sizeof(HASH64_NODE*) * hash_size); 160 } 161 else { 162 array = (HASH64_NODE**)mem_alloc_func(sizeof(HASH64_NODE*) * hash_size); 163 } 164 165 if (array == NULL) { 166 goto array_allocation_failed; 167 } 168 for (index = 0; index < hash_size; index++) { 169 array[index] = NULL; 170 } 171 172 // BEFORE_VMLAUNCH. CRITICAL check that should not fail. 173 VMM_ASSERT(node_alloc_func != NULL); 174 // BEFORE_VMLAUNCH. CRITICAL check that should not fail. 175 VMM_ASSERT(node_dealloc_func != NULL); 176 177 hash64_set_hash_size(hash, hash_size); 178 hash64_set_array(hash, array); 179 // BEFORE_VMLAUNCH. CRITICAL check that should not fail. 180 VMM_ASSERT(hash_func != NULL); 181 hash64_set_hash_func(hash, hash_func); 182 hash64_set_mem_alloc_func(hash, mem_alloc_func); 183 hash64_set_mem_dealloc_func(hash, mem_dealloc_func); 184 hash64_set_node_alloc_func(hash, node_alloc_func); 185 hash64_set_node_dealloc_func(hash, node_dealloc_func); 186 hash64_set_allocation_deallocation_context(hash, node_allocation_deallocation_context); 187 hash64_clear_element_count(hash); 188 if (is_multiple_values_hash) { 189 hash64_set_multiple_values_hash(hash); 190 } 191 else { 192 hash64_set_single_value_hash(hash); 193 } 194 return (HASH64_HANDLE)hash; 195 196 array_allocation_failed: 197 // BEFORE_VMLAUNCH. CRITICAL check that should not fail. 198 VMM_ASSERT(hash != NULL); 199 if (mem_dealloc_func == NULL) { 200 vmm_memory_free(hash); 201 } 202 else { 203 mem_dealloc_func(hash); 204 } 205 hash_allocation_failed: 206 return HASH64_INVALID_HANDLE; 207 } 208 209 static void hash64_destroy_hash_internal(HASH64_TABLE* hash) { 210 HASH64_INTERNAL_MEM_DEALLOCATION_FUNC mem_dealloc_func; 211 HASH64_NODE_DEALLOCATION_FUNC node_dealloc_func; 212 HASH64_NODE** array; 213 UINT32 i; 214 215 array = hash64_get_array(hash); 216 mem_dealloc_func = hash64_get_mem_dealloc_func(hash); 217 node_dealloc_func = hash64_get_node_dealloc_func(hash); 218 for (i = 0; i < hash64_get_hash_size(hash); i++) { 219 HASH64_NODE* node = array[i]; 220 221 if (hash64_get_element_count(hash) == 0) { 222 VMM_ASSERT(node == NULL); 223 break; 224 } 225 226 while (node != NULL) { 227 HASH64_NODE* next_node = hash64_node_get_next(node); 228 229 VMM_ASSERT(hash64_get_element_count(hash) != 0); 230 231 if (hash64_is_multiple_values_hash(hash)) { 232 UINT64 node_value = hash64_node_get_value(node); 233 HASH64_NODE* internal_node = (HASH64_NODE*)hash64_uint64_to_ptr(node_value); 234 while (internal_node != NULL) { 235 HASH64_NODE* next_internal_node = hash64_node_get_next(internal_node); 236 node_dealloc_func(hash64_get_allocation_deallocation_context(hash), internal_node); 237 internal_node = next_internal_node; 238 } 239 } 240 node_dealloc_func(hash64_get_allocation_deallocation_context(hash), node); 241 hash64_dec_element_count(hash); 242 node = next_node; 243 } 244 } 245 246 VMM_ASSERT(hash64_get_element_count(hash) == 0); 247 248 if (mem_dealloc_func == NULL) { 249 vmm_memory_free(array); 250 vmm_memory_free(hash); 251 } 252 else { 253 mem_dealloc_func(array); 254 mem_dealloc_func(hash); 255 } 256 } 257 258 259 UINT32 hash64_get_node_size(void) { 260 return sizeof(HASH64_NODE); 261 } 262 263 HASH64_HANDLE hash64_create_hash( HASH64_FUNC hash_func, 264 HASH64_INTERNAL_MEM_ALLOCATION_FUNC mem_alloc_func, 265 HASH64_INTERNAL_MEM_DEALLOCATION_FUNC mem_dealloc_func, 266 HASH64_NODE_ALLOCATION_FUNC node_alloc_func, 267 HASH64_NODE_DEALLOCATION_FUNC node_dealloc_func, 268 void* node_allocation_deallocation_context, 269 UINT32 hash_size) { 270 return hash64_create_hash_internal(hash_func, mem_alloc_func, 271 mem_dealloc_func, node_alloc_func, node_dealloc_func, 272 node_allocation_deallocation_context, hash_size, FALSE); 273 } 274 275 void hash64_destroy_hash(HASH64_HANDLE hash_handle) { 276 HASH64_TABLE* hash = (HASH64_TABLE*)hash_handle; 277 278 VMM_ASSERT(!hash64_is_multiple_values_hash(hash)); 279 hash64_destroy_hash_internal(hash); 280 } 281 282 UINT32 hash64_default_hash_func(UINT64 key, UINT32 size) 283 { 284 return (UINT32)(key % size); 285 } 286 287 #pragma warning (push) 288 #pragma warning (disable : 4100) 289 290 void* hash64_default_node_alloc_func(void* context UNUSED) 291 { 292 return vmm_memory_alloc(hash64_get_node_size()); 293 } 294 295 void hash64_default_node_dealloc_func(void* context UNUSED, void* data) 296 { 297 vmm_memory_free(data); 298 } 299 300 #pragma warning (pop) 301 302 303 HASH64_HANDLE hash64_create_default_hash(UINT32 hash_size) 304 { 305 return hash64_create_hash(hash64_default_hash_func, NULL, NULL, 306 hash64_default_node_alloc_func, hash64_default_node_dealloc_func, 307 NULL, hash_size); 308 } 309 310 BOOLEAN hash64_lookup(HASH64_HANDLE hash_handle, UINT64 key, UINT64* value) { 311 HASH64_TABLE* hash = (HASH64_TABLE*)hash_handle; 312 HASH64_NODE* node; 313 314 if (hash == NULL) { 315 return FALSE; 316 } 317 node = hash64_find(hash, key); 318 if (node != NULL) { 319 VMM_ASSERT(hash64_node_get_key(node) == key); 320 *value = hash64_node_get_value(node); 321 return TRUE; 322 } 323 return FALSE; 324 } 325 326 BOOLEAN hash64_insert(HASH64_HANDLE hash_handle, 327 UINT64 key, UINT64 value) { 328 HASH64_TABLE* hash = (HASH64_TABLE*)hash_handle; 329 330 if (hash == NULL) { 331 return FALSE; 332 } 333 return hash64_insert_internal(hash, key, value, FALSE); 334 } 335 336 BOOLEAN hash64_update(HASH64_HANDLE hash_handle, 337 UINT64 key, UINT64 value) { 338 HASH64_TABLE* hash = (HASH64_TABLE*)hash_handle; 339 340 if (hash == NULL) { 341 return FALSE; 342 } 343 return hash64_insert_internal(hash, key, value, TRUE); 344 } 345 346 BOOLEAN hash64_remove(HASH64_HANDLE hash_handle, 347 UINT64 key) { 348 HASH64_TABLE* hash = (HASH64_TABLE*)hash_handle; 349 HASH64_NODE* node; 350 HASH64_NODE** cell; 351 352 if (hash == NULL) { 353 return FALSE; 354 } 355 VMM_ASSERT(hash64_find(hash, key) != NULL); 356 cell = hash64_retrieve_appropriate_array_cell(hash, key); 357 node = *cell; 358 if (node == NULL) { 359 return FALSE; 360 } 361 if (hash64_node_get_key(node) == key) { 362 *cell = hash64_node_get_next(node); 363 VMM_ASSERT(hash64_find(hash, key) == NULL); 364 hash64_free_node(hash, node); 365 VMM_ASSERT(hash64_get_element_count(hash) > 0); 366 hash64_dec_element_count(hash); 367 return TRUE; 368 } 369 370 while(node != NULL) { 371 HASH64_NODE* prev_node = node; 372 node = hash64_node_get_next(node); 373 374 if ((node != NULL) && 375 (hash64_node_get_key(node) == key)) { 376 hash64_node_set_next(prev_node, hash64_node_get_next(node)); 377 VMM_ASSERT(hash64_find(hash, key) == NULL); 378 hash64_free_node(hash, node); 379 VMM_ASSERT(hash64_get_element_count(hash) > 0); 380 hash64_dec_element_count(hash); 381 return TRUE; 382 } 383 } 384 return FALSE; 385 } 386 387 BOOLEAN hash64_is_empty(HASH64_HANDLE hash_handle) { 388 HASH64_TABLE* hash = (HASH64_TABLE*)hash_handle; 389 390 if (hash == NULL) { 391 return FALSE; 392 } 393 394 return (hash64_get_element_count(hash) == 0); 395 } 396 397 BOOLEAN hash64_change_size_and_rehash(HASH64_HANDLE hash_handle, 398 UINT32 hash_size) { 399 HASH64_TABLE* hash = (HASH64_TABLE*)hash_handle; 400 HASH64_NODE** old_array; 401 HASH64_NODE** new_array; 402 UINT32 old_hash_size; 403 UINT32 i; 404 405 if (hash == NULL) { 406 return FALSE; 407 } 408 409 new_array = (HASH64_NODE**)hash64_mem_alloc(hash, sizeof(HASH64_NODE*) * hash_size); 410 411 if (new_array == NULL) { 412 return FALSE; 413 } 414 415 vmm_zeromem(new_array, sizeof(HASH64_NODE*) * hash_size); 416 417 old_array = hash64_get_array(hash); 418 old_hash_size = hash64_get_hash_size(hash); 419 420 hash64_set_array(hash, new_array); 421 hash64_set_hash_size(hash, hash_size); 422 423 for (i = 0; i < old_hash_size; i++) { 424 HASH64_NODE* node = old_array[i]; 425 while (node != NULL) { 426 HASH64_NODE* next_node = hash64_node_get_next(node); 427 UINT64 key; 428 HASH64_NODE** new_cell; 429 430 key = hash64_node_get_key(node); 431 new_cell = hash64_retrieve_appropriate_array_cell(hash, key); 432 hash64_node_set_next(node, *new_cell); 433 *new_cell = node; 434 435 node = next_node; 436 } 437 old_array[i] = NULL; 438 } 439 440 hash64_mem_free(hash, old_array); 441 return TRUE; 442 } 443 444 UINT32 hash64_get_num_of_elements(HASH64_HANDLE hash_handle) { 445 HASH64_TABLE* hash = (HASH64_TABLE*)hash_handle; 446 447 VMM_ASSERT(hash != NULL); 448 return hash64_get_element_count(hash); 449 } 450 #ifdef ENABLE_VTLB 451 UINT32 hash64_get_current_size(HASH64_HANDLE hash_handle) { 452 HASH64_TABLE* hash = (HASH64_TABLE*)hash_handle; 453 454 VMM_ASSERT(hash != NULL); 455 return hash64_get_hash_size(hash); 456 } 457 458 HASH64_HANDLE hash64_create_multiple_values_hash( HASH64_FUNC hash_func, 459 HASH64_INTERNAL_MEM_ALLOCATION_FUNC mem_alloc_func, 460 HASH64_INTERNAL_MEM_DEALLOCATION_FUNC mem_dealloc_func, 461 HASH64_NODE_ALLOCATION_FUNC node_alloc_func, 462 HASH64_NODE_DEALLOCATION_FUNC node_dealloc_func, 463 void* node_allocation_deallocation_context, 464 UINT32 hash_size) { 465 return hash64_create_hash_internal(hash_func, mem_alloc_func, 466 mem_dealloc_func, node_alloc_func, 467 node_dealloc_func, node_allocation_deallocation_context, 468 hash_size, TRUE); 469 } 470 #endif 471 472 473 void hash64_destroy_multiple_values_hash(HASH64_HANDLE hash_handle) { 474 HASH64_TABLE* hash = (HASH64_TABLE*)hash_handle; 475 476 VMM_ASSERT(hash64_is_multiple_values_hash(hash)); 477 hash64_destroy_hash_internal(hash); 478 } 479 480 #ifdef ENABLE_VTLB 481 BOOLEAN hash64_lookup_in_multiple_values_hash(HASH64_HANDLE hash_handle, 482 UINT64 key, HASH64_MULTIPLE_VALUES_HASH_ITERATOR* iter) { 483 HASH64_TABLE* hash = (HASH64_TABLE*)hash_handle; 484 HASH64_NODE* top_node; 485 UINT64 top_node_value; 486 487 if (hash == NULL) { 488 return FALSE; 489 } 490 VMM_ASSERT(hash64_is_multiple_values_hash(hash)); 491 top_node = hash64_find(hash, key); 492 if (top_node == NULL) { 493 return FALSE; 494 } 495 top_node_value = hash64_node_get_value(top_node); 496 *iter = (HASH64_MULTIPLE_VALUES_HASH_ITERATOR)hash64_uint64_to_ptr(top_node_value); 497 return TRUE; 498 } 499 500 501 HASH64_MULTIPLE_VALUES_HASH_ITERATOR 502 hash64_multiple_values_hash_iterator_get_next(HASH64_MULTIPLE_VALUES_HASH_ITERATOR iter) { 503 HASH64_NODE* node = (HASH64_NODE*)iter; 504 return (HASH64_MULTIPLE_VALUES_HASH_ITERATOR)hash64_node_get_next(node); 505 } 506 507 UINT64 hash64_multiple_values_hash_iterator_get_value( 508 HASH64_MULTIPLE_VALUES_HASH_ITERATOR iter) { 509 HASH64_NODE* node = (HASH64_NODE*)iter; 510 return hash64_node_get_value(node); 511 } 512 513 BOOLEAN hash64_insert_into_multiple_values_hash(HASH64_HANDLE hash_handle, 514 UINT64 key, UINT64 value) { 515 HASH64_TABLE* hash = (HASH64_TABLE*)hash_handle; 516 HASH64_NODE* top_node; 517 UINT64 top_node_value; 518 HASH64_NODE* node; 519 HASH64_NODE* node_tmp; 520 521 if (hash == NULL) { 522 return FALSE; 523 } 524 525 VMM_ASSERT(hash64_is_multiple_values_hash(hash)); 526 527 top_node = hash64_find(hash, key); 528 529 530 if (top_node == NULL) { 531 HASH64_NODE** cell; 532 top_node = hash64_allocate_node(hash); 533 if (top_node == NULL) { 534 return FALSE; 535 } 536 hash64_node_set_key(top_node, key); 537 hash64_node_set_value(top_node, hash64_ptr_to_uint64(NULL)); 538 cell = hash64_retrieve_appropriate_array_cell(hash, key); 539 hash64_node_set_next(top_node, *cell); 540 *cell = top_node; 541 hash64_inc_element_count(hash); 542 } 543 544 node = hash64_allocate_node(hash); 545 if (node == NULL) { 546 return FALSE; 547 } 548 549 hash64_node_set_key(node, key); 550 hash64_node_set_value(node, value); 551 552 top_node_value = hash64_node_get_value(top_node); 553 node_tmp = (HASH64_NODE*)hash64_uint64_to_ptr(top_node_value); 554 if ((node_tmp == NULL) || 555 (hash64_node_get_value(node_tmp) >= value)) { 556 hash64_node_set_next(node, node_tmp); 557 hash64_node_set_value(top_node, hash64_ptr_to_uint64(node)); 558 return TRUE; 559 } 560 561 while (1) { 562 HASH64_NODE* next_node_tmp = hash64_node_get_next(node_tmp); 563 if ((next_node_tmp == NULL) || 564 (hash64_node_get_value(next_node_tmp) >= value)) { 565 break; 566 } 567 node_tmp = next_node_tmp; 568 } 569 570 hash64_node_set_next(node, hash64_node_get_next(node_tmp)); 571 hash64_node_set_next(node_tmp, node); 572 573 return TRUE; 574 } 575 576 BOOLEAN hash64_remove_from_multiple_values_hash(HASH64_HANDLE hash_handle, 577 UINT64 key, UINT64 value) { 578 HASH64_TABLE* hash = (HASH64_TABLE*)hash_handle; 579 HASH64_NODE* top_node; 580 UINT64 top_node_value; 581 HASH64_NODE* node; 582 583 if (hash == NULL) { 584 return FALSE; 585 } 586 587 VMM_ASSERT(hash64_is_multiple_values_hash(hash)); 588 589 top_node = hash64_find(hash, key); 590 591 if (top_node == NULL) { 592 return FALSE; 593 } 594 595 top_node_value = hash64_node_get_value(top_node); 596 node = (HASH64_NODE*)hash64_uint64_to_ptr(top_node_value); 597 598 if (hash64_node_get_value(node) == value) { 599 HASH64_NODE* next_node = hash64_node_get_next(node); 600 hash64_free_node(hash, node); 601 top_node_value = hash64_ptr_to_uint64(next_node); 602 hash64_node_set_value(top_node, top_node_value); 603 if (next_node == NULL) { 604 BOOLEAN res; 605 // There is only one value 606 res = hash64_remove(hash_handle, key); 607 VMM_ASSERT(res); 608 } 609 return TRUE; 610 } 611 612 while (node != NULL) { 613 HASH64_NODE* prev_node = node; 614 615 node = hash64_node_get_next(node); 616 if (node != NULL) { 617 if (hash64_node_get_value(node) == value) { 618 hash64_node_set_next(prev_node, hash64_node_get_next(node)); 619 hash64_free_node(hash, node); 620 return TRUE; 621 } 622 else if (hash64_node_get_value(node) > value) { 623 break; // no point to search in sorted list 624 } 625 } 626 } 627 return FALSE; 628 } 629 630 BOOLEAN hash64_is_value_in_multiple_values_hash(HASH64_HANDLE hash_handle, 631 UINT64 key, UINT64 value) { 632 HASH64_TABLE* hash = (HASH64_TABLE*)hash_handle; 633 HASH64_MULTIPLE_VALUES_HASH_ITERATOR iter; 634 635 if (hash == NULL) { 636 return FALSE; 637 } 638 639 VMM_ASSERT(hash64_is_multiple_values_hash(hash)); 640 641 if (!hash64_lookup_in_multiple_values_hash(hash_handle, key, &iter)) { 642 return FALSE; 643 } 644 645 while (iter != HASH64_NULL_ITERATOR) { 646 UINT64 iter_value = hash64_multiple_values_hash_iterator_get_value(iter); 647 if (iter_value == value) { 648 return TRUE; 649 } 650 iter = hash64_multiple_values_hash_iterator_get_next(iter); 651 } 652 return FALSE; 653 } 654 655 BOOLEAN hash64_remove_range_from_multiple_values_hash(HASH64_HANDLE hash_handle, 656 UINT64 key, UINT64 value_from, UINT64 value_to) { 657 HASH64_TABLE* hash = (HASH64_TABLE*)hash_handle; 658 HASH64_NODE* top_node; 659 HASH64_NODE* node; 660 UINT64 top_node_value; 661 BOOLEAN removed_any_value = FALSE; 662 663 if (hash == NULL) { 664 return FALSE; 665 } 666 667 VMM_ASSERT(hash64_is_multiple_values_hash(hash)); 668 669 top_node = hash64_find(hash, key); 670 671 if (top_node == NULL) { 672 return FALSE; 673 } 674 675 top_node_value = hash64_node_get_value(top_node); 676 node = (HASH64_NODE*)hash64_uint64_to_ptr(top_node_value); 677 678 VMM_ASSERT(node != NULL); 679 VMM_ASSERT(value_from <= value_to); 680 681 if (hash64_node_get_value(node) > value_to) { 682 return FALSE; 683 } 684 685 if (hash64_node_get_value(node) >= value_from) { 686 while ((node != NULL) && 687 (hash64_node_get_value(node) <= value_to)) { 688 // remove from the beginning of the list 689 HASH64_NODE* node_to_remove = node; 690 node = hash64_node_get_next(node); 691 hash64_free_node(hash, node_to_remove); 692 removed_any_value = TRUE; 693 } 694 695 if (removed_any_value) { 696 VMM_ASSERT((node == NULL) || (hash64_node_get_value(node) > value_to)); 697 top_node_value = hash64_ptr_to_uint64(node); 698 hash64_node_set_value(top_node, top_node_value); 699 if (node == NULL) { 700 BOOLEAN res; 701 // all the entries were removed 702 res = hash64_remove(hash_handle, key); 703 VMM_ASSERT(res); 704 } 705 return TRUE; 706 } 707 } 708 709 while (node != NULL) { 710 HASH64_NODE* next_node = hash64_node_get_next(node); 711 VMM_ASSERT(hash64_node_get_value(node) < value_from); 712 if ((next_node != NULL) && 713 (hash64_node_get_value(next_node) > value_to)) { 714 break; 715 } 716 717 if ((next_node != NULL) && 718 (hash64_node_get_value(next_node) >= value_from)) { 719 hash64_node_set_next(node, hash64_node_get_next(next_node)); 720 hash64_free_node(hash, next_node); 721 removed_any_value = TRUE; 722 } 723 else { 724 node = next_node; 725 } 726 } 727 return removed_any_value; 728 } 729 730 BOOLEAN hash64_multiple_values_is_empty(HASH64_HANDLE hash_handle) { 731 HASH64_TABLE* hash = (HASH64_TABLE*)hash_handle; 732 733 if (hash == NULL) { 734 return FALSE; 735 } 736 737 return (hash64_get_element_count(hash) == 0); 738 } 739 #endif 740 741 #ifdef DEBUG 742 void hash64_print(HASH64_HANDLE hash_handle) { 743 HASH64_TABLE* hash = (HASH64_TABLE*)hash_handle; 744 HASH64_NODE** array; 745 UINT32 i; 746 747 VMM_LOG(mask_anonymous, level_trace,"Hash64:\n"); 748 VMM_LOG(mask_anonymous, level_trace,"========================\n"); 749 if (hash == NULL) { 750 VMM_LOG(mask_anonymous, level_trace,"%s: ERROR in parameter\n", __FUNCTION__); 751 return; 752 } 753 VMM_LOG(mask_anonymous, level_trace,"Num of cells: %d\n", hash64_get_hash_size(hash)); 754 VMM_LOG(mask_anonymous, level_trace,"Num of elements: %d\n", hash64_get_element_count(hash)); 755 756 array = hash64_get_array(hash); 757 for (i = 0; i < hash64_get_hash_size(hash); i++) { 758 if (array[i] != NULL) { 759 HASH64_NODE* node = array[i]; 760 VMM_LOG(mask_anonymous, level_trace,"[%d]: ", i); 761 762 while (node != NULL) { 763 if (hash64_is_multiple_values_hash(hash)) { 764 UINT32 counter = 0; 765 HASH64_NODE* node_value = hash64_uint64_to_ptr(hash64_node_get_value(node)); 766 while (node_value != NULL) { 767 counter++; 768 node_value = hash64_node_get_next(node_value); 769 } 770 VMM_LOG(mask_anonymous, level_trace,"(%P : %d); ", hash64_node_get_key(node), counter); 771 } 772 else { 773 VMM_LOG(mask_anonymous, level_trace,"(%P : %P); ", hash64_node_get_key(node), hash64_node_get_value(node)); 774 } 775 node = hash64_node_get_next(node); 776 } 777 778 VMM_LOG(mask_anonymous, level_trace,"\n"); 779 } 780 } 781 } 782 #endif 783