// String interning thingy package name import "core:mem" import "core:strings" import "core:sync" Name :: distinct u32 NONE :: Name(0) Container :: struct { lock: sync.Atomic_RW_Mutex, names_lookup: map[string]Name, names_allocator: mem.Dynamic_Arena, names_array: [dynamic]string, } @(private = "file") global_container: ^Container setup_global_container :: proc(cnt: ^Container) { global_container = cnt } init :: proc(cnt: ^Container) { mem.dynamic_arena_init(&cnt.names_allocator) assert(len(cnt.names_array) == 0) append(&cnt.names_array, "None") } destroy :: proc() { assert(global_container != nil) delete(global_container.names_array) delete(global_container.names_lookup) mem.dynamic_arena_destroy(&global_container.names_allocator) global_container = nil } from_string :: proc(str: string) -> Name { sync.atomic_rw_mutex_guard(&global_container.lock) existing, ok := global_container.names_lookup[str] if ok { return existing } else { new_str := strings.clone( str, mem.dynamic_arena_allocator(&global_container.names_allocator), ) idx := u32(len(global_container.names_array)) append(&global_container.names_array, new_str) global_container.names_lookup[str] = Name(idx) return Name(idx) } } to_string :: proc(name: Name) -> string { sync.atomic_rw_mutex_shared_guard(&global_container.lock) return global_container.names_array[name] }