aboutsummaryrefslogtreecommitdiff
path: root/dep/CascLib/src/common/IndexMap.h
diff options
context:
space:
mode:
Diffstat (limited to 'dep/CascLib/src/common/IndexMap.h')
-rw-r--r--dep/CascLib/src/common/IndexMap.h106
1 files changed, 106 insertions, 0 deletions
diff --git a/dep/CascLib/src/common/IndexMap.h b/dep/CascLib/src/common/IndexMap.h
new file mode 100644
index 00000000000..fe6b007cc7e
--- /dev/null
+++ b/dep/CascLib/src/common/IndexMap.h
@@ -0,0 +1,106 @@
+/*****************************************************************************/
+/* IndexMap.h Copyright (c) Ladislav Zezula 2019 */
+/*---------------------------------------------------------------------------*/
+/* Interface of index-based map for CascLib. This is a map type created */
+/* on top of an array of contant-size objects, that is already sorted. */
+/*---------------------------------------------------------------------------*/
+/* Date Ver Who Comment */
+/* -------- ---- --- ------- */
+/* 29.04.19 1.00 Lad The first version of Index.h */
+/*****************************************************************************/
+
+#ifndef __CASC_INDEX_MAP_H__
+#define __CASC_INDEX_MAP_H__
+
+//-----------------------------------------------------------------------------
+// Structures
+
+class CASC_INDEX_MAP
+{
+ public:
+
+ int Create(size_t MaxItems, size_t ObjectLength_, size_t KeyLength_, size_t KeyOffset_)
+ {
+ DWORD IndexBitSize = 8;
+
+ // Determine the index size
+ if(MaxItems >= 0x10000)
+ IndexBitSize = 16;
+ if(MaxItems >= 0x100000)
+ IndexBitSize = 20;
+
+ // Save the values
+ IndexTableSize = (1 << IndexBitSize);
+ IndexTableMask = IndexTableSize - 1;
+ ObjectLength = ObjectLength_;
+ KeyOffset = KeyOffset_;
+ KeyLength = KeyLength_;
+
+ // Allocate the new index object
+ IndexTable = CASC_ALLOC(void *, IndexTableSize);
+ if(IndexTable != NULL)
+ {
+ memset(IndexTable, 0, IndexTableSize * sizeof(void *));
+ return ERROR_SUCCESS;
+ }
+
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ void * FindObject(void * pvKey)
+ {
+ LPBYTE StartObject;
+ DWORD StartIndex;
+
+ // Verify pointer to the map
+ if(IndexTable != NULL)
+ {
+ // Retrieve the index from the key
+ StartIndex = KeyToIndex(pvKey);
+ StartObject = (LPBYTE)IndexTable[StartIndex];
+ if(StartObject == NULL)
+ return NULL;
+
+ // Enumerate the array as long as the index matches
+ do
+ {
+ // Compare the key
+ if(!memcmp(StartObject + KeyOffset, pvKey, KeyLength))
+ return StartObject;
+
+ // Key mismatch -> go next object
+ StartObject = StartObject + ObjectLength;
+ }
+ while(KeyToIndex(StartObject + KeyOffset) == StartIndex);
+ }
+
+ // Not found
+ return NULL;
+ }
+
+ protected:
+
+ inline DWORD KeyToIndex(void * pvKey)
+ {
+ return *((PDWORD)pvKey) & IndexTableMask;
+ }
+
+ void ** IndexTable; // Pointer table. Each entry, if non-NULL, contains a pointer to the first object
+ // into a sorted array. Search function must then match the entire key.
+ // In case of no match, the search process must go to the next-in-array object.
+ size_t ObjectLength; // Length of the single object
+ size_t KeyOffset; // How far is the key from the begin of the structure (in bytes)
+ size_t KeyLength; // Length of the key
+ DWORD IndexTableSize; // Size of the IndexTableSize, in bytes
+ DWORD IndexTableMask; // Bit mask for conversion from hash to index
+};
+
+typedef CASC_INDEX_MAP *PCASC_INDEX_MAP;
+
+//-----------------------------------------------------------------------------
+// Functions
+
+bool IndexMap_InsertObject(PCASC_INDEX_MAP pIndexMap, void * pvNewObject, void * pvKey);
+void IndexMap_Free(PCASC_INDEX_MAP pIndexMap);
+
+#endif // __CASC_INDEX_MAP_H__