Files
handleaiuinew/env/LMI/include/kApi/Data/kMap.x.h
T
2024-05-18 23:53:26 +08:00

264 lines
8.5 KiB
C

/**
* @file kMap.x.h
*
* @internal
* Copyright (C) 2012-2021 by LMI Technologies Inc.
* Licensed under the MIT License.
* Redistributed files must retain the above copyright notice.
*/
#ifndef K_API_MAP_X_H
#define K_API_MAP_X_H
#define xkMAP_CAPACITY_TO_BUCKETS(C) (5*(C)/4) //determines minimum buckets, assuming max load of 0.75
#define xkMAP_MIN_ITEMS_PER_BLOCK (16) //minimum number of map items per allocated memory block
//represents a single key/value map entry
typedef struct kMapItemStruct //<K, V>
{
struct kMapItemStruct* next; //linked list pointer to next item
kSize hashCode; //cached hash code
//K key; //key; offset/size dynamically calculated
//V value; //value; offset/size dynamically calculated
} kMapItemStruct;
//represents a block of allocated map items; multiple items
//are allocated at the same time for efficiency
typedef struct kMapItemBlock //<N>
{
struct kMapItemBlock* next; //linked list pointer to next memory block
kSize itemCount; //count of items in block (N)
kMapItemStruct* items; //pointer to first item in block
//kMapItemStruct item[N]; //array of map items
} kMapItemBlock;
typedef struct kMapClass
{
kObjectClass base; // base fields
kMapItemBlock* blocks; // allocated memory blocks, where block contains N items
kMapItemStruct* free; // linked list of free items
kMapItemStruct** buckets; // array of buckets, where each bucket is a linked list of items
kSize bucketCount; // count of buckets
kSize count; // current count of items
kSize capacity; // maximum number of items before allocation required
xkStructField keyField; // key field info
xkStructField valueField; // value field info
kSize itemSize; // size of map item, including key and value fields
kEqualsFx equalsFx; // callback function for equality comparison
kHashFx hashFx; // callback function for hash code generation
void* collectionItem; // temp variable, required to implement kCollection interface
} kMapClass;
kDeclareClassEx(k, kMap, kObject)
/*
* Forward declarations.
*/
kFx(kStatus) kMap_Find(kMap map, const void* key, void* value);
kInlineFx(kBool) kMap_Has(kMap map, const void* key);
kFx(kStatus) kMap_Add(kMap map, const void* key, const void* value);
kFx(kStatus) kMap_Replace(kMap map, const void* key, const void* value);
kFx(kStatus) kMap_Remove(kMap map, const void* key, void* oldKey, void* oldValue);
kInlineFx(kStatus) kMap_Discard(kMap map, const void* key);
kFx(kStatus) kMap_FindItem(kMap map, const void* key, kMapItem* item);
kFx(kStatus) kMap_RemoveItem(kMap map, kMapItem item);
kInlineFx(kStatus) kMap_SetValue(kMap map, kMapItem item, const void* value);
kFx(kStatus) kMap_Purge(kMap map);
kInlineFx(const void*) kMap_Key(kMap map, kMapItem item);
kInlineFx(void*) kMap_Value(kMap map, kMapItem item);
kInlineFx(kType) kMap_KeyType(kMap map);
kInlineFx(kType) kMap_ValueType(kMap map);
/*
* Private methods.
*/
kFx(kStatus) xkMap_ConstructFramework(kMap* map, kAlloc allocator);
kFx(kStatus) xkMap_Init(kMap map, kType classType, kType keyType, kType valueType, kSize initialCapacity, kAlloc alloc);
kFx(kStatus) xkMap_VClone(kMap map, kMap source, kAlloc valueAlloc, kObject context);
kFx(kStatus) xkMap_VRelease(kMap map);
kInlineFx(kStatus) xkMap_VDisposeItems(kMap map)
{
return kMap_Purge(map);
}
kFx(kBool) xkMap_VHasShared(kMap map);
kFx(kSize) xkMap_VSize(kMap map);
kFx(kAllocTrait) xkMap_VAllocTraits(kMap map);
kFx(kStatus) xkMap_WriteDat6V0(kMap map, kSerializer serializer);
kFx(kStatus) xkMap_ReadDat6V0(kMap map, kSerializer serializer);
kFx(kStatus) xkMap_Deallocate(kMap map);
kFx(kStatus) xkMap_Layout(kMap map, kType keyType, kType valueType);
kFx(kStatus) xkMap_ReserveItems(kMap map, kSize capacity);
kFx(kStatus) xkMap_ReserveBuckets(kMap map);
kFx(kStatus) xkMap_Rehash(kMap map);
kInlineFx(kBool) xkMap_KeyIsRef(kMap map)
{
return kType_IsReference(kMap_KeyType(map));
}
kInlineFx(kBool) xkMap_ValueIsRef(kMap map)
{
return kType_IsReference(kMap_ValueType(map));
}
kInlineFx(kSize) xkMap_HashToIndex(kSize code, kSize count)
{
return code & (count - 1);
}
kInlineFx(kSize) xkMap_BucketIndex(kMap map, kSize code)
{
kObj(kMap, map);
return xkMap_HashToIndex(code, obj->bucketCount);
}
kInlineFx(kSize) xkMap_HashKey(kMap map, const void* key)
{
kObj(kMap, map);
if (obj->hashFx)
{
return obj->hashFx(key);
}
else
{
if (xkMap_KeyIsRef(map))
{
return kObject_HashCode(kPointer_ReadAs(key, kObject));
}
else
{
return kValue_HashCode(kMap_KeyType(map), key);
}
}
}
kInlineFx(kBool) xkMap_KeyEquals(kMap map, const void* key1, const void* key2)
{
kObj(kMap, map);
if (obj->equalsFx)
{
return obj->equalsFx(key1, key2);
}
else
{
if (xkMap_KeyIsRef(map))
{
return kObject_Equals(kPointer_ReadAs(key1, kObject), kPointer_ReadAs(key2, kObject));
}
else
{
return kValue_Equals(kMap_KeyType(map), key1, key2);
}
}
}
kInlineFx(kSize) xkMapItem_HashCode(kMap map, kMapItem item)
{
return kCast(kMapItemStruct*, item)->hashCode;
}
kInlineFx(kStatus) xkMap_FindT(kMap map, const void* key, void* value, kSize keySize, kSize valueSize)
{
kAssert(xkType_IsPointerCompatible(kMap_KeyType(map), keySize));
kAssert(xkType_IsPointerCompatible(kMap_ValueType(map), valueSize));
return kMap_Find(map, key, value);
}
kInlineFx(kBool) xkMap_HasT(kMap map, const void* key, kSize keySize)
{
kAssert(xkType_IsPointerCompatible(kMap_KeyType(map), keySize));
return kMap_Has(map, key);
}
kInlineFx(kStatus) xkMap_AddT(kMap map, const void* key, const void* value, kSize keySize, kSize valueSize)
{
kAssert(xkType_IsPointerCompatible(kMap_KeyType(map), keySize));
kAssert(xkType_IsPointerCompatible(kMap_ValueType(map), valueSize));
return kMap_Add(map, key, value);
}
kInlineFx(kStatus) xkMap_ReplaceT(kMap map, const void* key, const void* value, kSize keySize, kSize valueSize)
{
kAssert(xkType_IsPointerCompatible(kMap_KeyType(map), keySize));
kAssert(xkType_IsPointerCompatible(kMap_ValueType(map), valueSize));
return kMap_Replace(map, key, value);
}
kInlineFx(kStatus) xkMap_RemoveT(kMap map, const void* key, void* oldKey, void* oldValue, kSize keySize, kSize oldKeySize, kSize oldValueSize)
{
kAssert(xkType_IsPointerCompatible(kMap_KeyType(map), keySize));
kAssert(xkType_IsPointerCompatible(kMap_KeyType(map), oldKeySize));
kAssert(xkType_IsPointerCompatible(kMap_ValueType(map), oldValueSize));
return kMap_Remove(map, key, oldKey, oldValue);
}
kInlineFx(kStatus) xkMap_DiscardT(kMap map, const void* key, kSize keySize)
{
kAssert(xkType_IsPointerCompatible(kMap_KeyType(map), keySize));
return kMap_Discard(map, key);
}
kInlineFx(kStatus) xkMap_FindItemT(kMap map, const void* key, kMapItem* item, kSize keySize)
{
kAssert(xkType_IsPointerCompatible(kMap_KeyType(map), keySize));
return kMap_FindItem(map, key, item);
}
kInlineFx(kStatus) xkMap_SetValueT(kMap map, kMapItem item, const void* value, kSize valueSize)
{
kAssert(xkType_IsPointerCompatible(kMap_ValueType(map), valueSize));
return kMap_SetValue(map, item, value);
}
kInlineFx(const void*) xkMap_KeyT(kMap map, kMapItem item, kSize keySize)
{
kAssert(xkType_IsPointerCompatible(kMap_KeyType(map), keySize));
return kMap_Key(map, item);
}
kInlineFx(void*) xkMap_ValueT(kMap map, kMapItem item, kSize valueSize)
{
kAssert(xkType_IsPointerCompatible(kMap_ValueType(map), valueSize));
return kMap_Value(map, item);
}
kInlineFx(const void*) xkMap_KeyAsT(kMap map, kMapItem item, kSize keySize)
{
kAssert(keySize == kType_Size(kMap_KeyType(map)));
return kMap_Key(map, item);
}
kInlineFx(void*) xkMap_ValueAsT(kMap map, kMapItem item, kSize valueSize)
{
kAssert(valueSize == kType_Size(kMap_ValueType(map)));
return kMap_Value(map, item);
}
#endif