#include "hashmap.h" #include "utils.h" // ======================= // ====== windows.h ====== // ======================= #define PAGE_NOACCESS 0x01 #define PAGE_READONLY 0x02 #define PAGE_READWRITE 0x04 #define PAGE_WRITECOPY 0x08 #define PAGE_EXECUTE 0x10 #define PAGE_EXECUTE_READ 0x20 #define PAGE_EXECUTE_READWRITE 0x40 #define PAGE_EXECUTE_WRITECOPY 0x80 #define PAGE_GUARD 0x100 #define PAGE_NOCACHE 0x200 #define PAGE_WRITECOMBINE 0x400 #define PAGE_GRAPHICS_NOACCESS 0x0800 #define PAGE_GRAPHICS_READONLY 0x1000 #define PAGE_GRAPHICS_READWRITE 0x2000 #define PAGE_GRAPHICS_EXECUTE 0x4000 #define PAGE_GRAPHICS_EXECUTE_READ 0x8000 #define PAGE_GRAPHICS_EXECUTE_READWRITE 0x10000 #define PAGE_GRAPHICS_COHERENT 0x20000 #define PAGE_GRAPHICS_NOCACHE 0x40000 #define PAGE_ENCLAVE_THREAD_CONTROL 0x80000000 #define PAGE_REVERT_TO_FILE_MAP 0x80000000 #define PAGE_TARGETS_NO_UPDATE 0x40000000 #define PAGE_TARGETS_INVALID 0x40000000 #define PAGE_ENCLAVE_UNVALIDATED 0x20000000 #define PAGE_ENCLAVE_MASK 0x10000000 #define PAGE_ENCLAVE_DECOMMIT (PAGE_ENCLAVE_MASK | 0) #define PAGE_ENCLAVE_SS_FIRST (PAGE_ENCLAVE_MASK | 1) #define PAGE_ENCLAVE_SS_REST (PAGE_ENCLAVE_MASK | 2) #define MEM_COMMIT 0x00001000 #define MEM_RESERVE 0x00002000 #define MEM_REPLACE_PLACEHOLDER 0x00004000 #define MEM_RESERVE_PLACEHOLDER 0x00040000 #define MEM_RESET 0x00080000 #define MEM_TOP_DOWN 0x00100000 #define MEM_WRITE_WATCH 0x00200000 #define MEM_PHYSICAL 0x00400000 #define MEM_ROTATE 0x00800000 #define MEM_DIFFERENT_IMAGE_BASE_OK 0x00800000 #define MEM_RESET_UNDO 0x01000000 #define MEM_LARGE_PAGES 0x20000000 #define MEM_4MB_PAGES 0x80000000 #define MEM_64K_PAGES (MEM_LARGE_PAGES | MEM_PHYSICAL) #define MEM_UNMAP_WITH_TRANSIENT_BOOST 0x00000001 #define MEM_COALESCE_PLACEHOLDERS 0x00000001 #define MEM_PRESERVE_PLACEHOLDER 0x00000002 #define MEM_DECOMMIT 0x00004000 #define MEM_RELEASE 0x00008000 #define MEM_FREE 0x00010000 #define MEM_EXTENDED_PARAMETER_GRAPHICS 0x00000001 #define MEM_EXTENDED_PARAMETER_NONPAGED 0x00000002 #define MEM_EXTENDED_PARAMETER_ZERO_PAGES_OPTIONAL 0x00000004 #define MEM_EXTENDED_PARAMETER_NONPAGED_LARGE 0x00000008 #define MEM_EXTENDED_PARAMETER_NONPAGED_HUGE 0x00000010 #define MEM_EXTENDED_PARAMETER_SOFT_FAULT_PAGES 0x00000020 #define MEM_EXTENDED_PARAMETER_EC_CODE 0x00000040 #define MEM_EXTENDED_PARAMETER_NUMA_NODE_MANDATORY MINLONG64 extern void* VirtualAlloc(void* lpAddress, size_t dwSize, u32 flAllocationType, u32 flProtect); extern i32 VirtualFree(void* lpAddress, size_t dwSize, u32 dwFreeType); // ======================== // ====== !windows.h ====== // ======================== static const u32 initial_size = 4096U * 100U; static const u32 empty_psl = (u32)-1; static const float max_load_factor = 0.75f; void resize(struct hashmap* map) { void* alloc = VirtualAlloc((void*)(map->arr + 1U), map->capacity * sizeof(struct element), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); if (alloc == NULL) { alloc = VirtualAlloc(NULL, map->capacity * 2U * sizeof(struct element), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); map->capacity *= 2U; // copy elements + rehashing } else { map->capacity *= 2U; // rehashing } } struct hashmap create_unordered_flat() { struct hashmap map = { .capacity = initial_size / sizeof(struct element), .size = 0U, .arr = (struct element*)VirtualAlloc(NULL, initial_size * sizeof(struct element), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE), }; for (u32 index = 0U; index < map.capacity; index++) { map.arr[index].name = 0ULL; map.arr[index].start = 0U; map.arr[index].end = 0U; map.arr[index].psl = 0U; } return map; } struct element* insert_elem(struct hashmap* map, u32 start, u32 end, u64 name) { if (map->size >= map->capacity) { return NULL; } float load = map->size / (float)map->capacity; if (load >= max_load_factor) { resize(map); } u32 index = start % map->capacity; u32 psl = 0U; while(map->arr[index + psl].name != 0ULL || (map->arr[index + psl].psl >= psl && map->arr[index + psl].psl != 0U)) { psl++; } map->arr[index + psl].name = name; map->arr[index + psl].start = start; map->arr[index + psl].end = end; map->arr[index + psl].psl = psl; map->size++; return &map->arr[index + psl]; } void remove_elem(struct hashmap* map, u32 start) { u32 index = start % map->capacity; while (map->arr[index].start != start) { index++; } while (map->arr[index].name != 0U && map->arr[index].psl != empty_psl && index < map->capacity) { map->arr[index - 1U].psl = map->arr[index].psl - 1U; map->arr[index - 1U].start = map->arr[index].start; map->arr[index - 1U].end = map->arr[index].end; map->arr[index - 1U].name = map->arr[index].name; index++; } map->arr[index].psl = empty_psl; } struct element* find_elem(struct hashmap* map, u32 start) { u32 index = start % map->capacity; while (index < map->capacity) { if (map->arr[index].start == start) { return &map->arr[index]; } index++; } return NULL; } void iterate(struct hashmap* map) { u32 counter = 0U; for (u32 index = 0U; index < map->capacity && counter < map->size; index++) { if (map->arr[index].name) { print("%s\n", map->arr[index].name); counter++; } } }