27#include "mem_blockalloc.h"
30# include "../fgame/g_local.h"
32# define SET_Alloc gi.Malloc
33# define SET_Free gi.Free
35#elif defined(CGAME_DLL)
36# include "../cgame/cg_local.h"
38# define SET_Alloc cgi.Malloc
39# define SET_Free cgi.Free
42# include "../renderercommon/tr_common.h"
44# define SET_Alloc ri.Malloc
45# define SET_Free ri.Free
50# define SET_Alloc Z_Malloc
51# define SET_Free Z_Free
57template<
typename k,
typename v>
60template<
typename key,
typename value>
63template<
typename key,
typename value>
66template<
typename key,
typename value>
71 static const bool con_value =
false;
76 static const bool con_value =
true;
85template<
typename k,
typename v>
99 void *
operator new(
size_t size) {
return con_set<k, v>::NewEntry(size); }
101 void operator delete(
void *ptr) { con_set<k, v>::DeleteEntry(ptr); }
109#ifdef ARCHIVE_SUPPORTED
112 k& GetKey() {
return key; }
114 void SetKey(
const k& newKey) { key = newKey; }
117template<
typename k,
typename v>
130 unsigned int tableLength;
131 unsigned int threshold;
133 short unsigned int tableLengthIndex;
137 Entry *findKeyEntry(
const k& key)
const;
138 Entry *addKeyEntry(
const k& key);
139 Entry *addNewKeyEntry(
const k& key);
142 static void *NewEntry(
size_t size);
143 static void DeleteEntry(
void *entry);
144 static void *NewTable(
size_t count);
145 static void DeleteTable(
void *table);
151#ifdef ARCHIVE_SUPPORTED
156 void resize(
int count = 0);
158 v *findKeyValue(
const k& key)
const;
161 v& addKeyValue(
const k& key);
162 v& addNewKeyValue(
const k& key);
164 bool keyExists(
const k& key);
166 bool remove(
const k& key);
171template<
typename k,
typename v>
174template<
typename k,
typename v>
175void *con_set<k, v>::NewEntry(
size_t size)
177 return Entry_allocator.Alloc();
180template<
typename k,
typename v>
181void con_set<k, v>::DeleteEntry(
void *entry)
183 Entry_allocator.Free(entry);
186template<
typename k,
typename v>
187void *con_set<k, v>::NewTable(
size_t count)
189 return SET_Alloc(
sizeof(Entry *) * (
int)count);
192template<
typename k,
typename v>
193void con_set<k, v>::DeleteTable(
void *table)
199int HashCode(
const k& key);
201template<
typename key,
typename value>
202con_set<key, value>::con_set()
205 table = &defaultEntry;
209 tableLengthIndex = 0;
214template<
typename key,
typename value>
215con_set<key, value>::~con_set()
220template<
typename key,
typename value>
221void con_set<key, value>::clear()
227 for (i = 0; i < tableLength; i++) {
228 for (entry = table[i]; entry != NULL; entry = next) {
234 if (tableLength > 1) {
239 table = &defaultEntry;
243 tableLengthIndex = 0;
248template<
typename key,
typename value>
249void con_set<key, value>::resize(
int count)
251 Entry **oldTable = table;
253 unsigned int oldTableLength = tableLength;
258 tableLength += count;
259 threshold = tableLength;
262 threshold = (
unsigned int)((
float)tableLength * 0.75);
267 tableLength += threshold;
271 table =
new (NewTable(tableLength)) Entry *[tableLength]();
274 for (i = oldTableLength; i > 0; i--) {
276 for (e = oldTable[i - 1]; e != NULL; e = old) {
280 index = HashCode<key>(e->GetKey()) % tableLength;
282 e->next = table[index];
287 if (oldTableLength > 1) {
289 DeleteTable(oldTable);
293template<
typename k,
typename v>
294typename con_set<k, v>::Entry *con_set<k, v>::findKeyEntry(
const k& key)
const
298 entry = table[HashCode<k>(key) % tableLength];
300 for (; entry != NULL; entry = entry->next) {
301 if (entry->GetKey() == key) {
309template<
typename k,
typename v>
310typename con_set<k, v>::Entry *con_set<k, v>::addKeyEntry(
const k& key)
314 entry = findKeyEntry(key);
319 return addNewKeyEntry(key);
323template<
typename k,
typename v>
324typename con_set<k, v>::Entry *con_set<k, v>::addNewKeyEntry(
const k& key)
329 if (count >= threshold) {
337 hash = HashCode<k>(entry->GetKey()) % tableLength;
339 if (defaultEntry == NULL) {
340 defaultEntry = entry;
343 entry->next = table[hash];
350template<
typename key,
typename value>
351bool con_set<key, value>::isEmpty(
void)
356template<
typename k,
typename v>
357bool con_set<k, v>::remove(
const k& key)
364 hash = HashCode<k>(key) % tableLength;
366 for (entry = table[hash]; entry != NULL; entry = entry->next) {
368 if (!(entry->GetKey() == key)) {
373 if (defaultEntry == entry) {
374 defaultEntry = prev ? prev : table[hash];
376 for (i = 0; i < tableLength && !defaultEntry; i++) {
377 for (e = table[i]; e; e = e->next) {
388 prev->next = entry->next;
390 table[hash] = entry->next;
402template<
typename k,
typename v>
403v *con_set<k, v>::findKeyValue(
const k& key)
const
405 Entry *entry = findKeyEntry(key);
408 return &entry->value;
414template<
typename key,
typename value>
415key *con_set<key, value>::firstKeyValue(
void)
418 return &defaultEntry->GetKey();
424template<
typename k,
typename v>
425v& con_set<k, v>::addKeyValue(
const k& key)
427 Entry *entry = addKeyEntry(key);
432template<
typename k,
typename v>
433v& con_set<k, v>::addNewKeyValue(
const k& key)
435 Entry *entry = addNewKeyEntry(key);
440template<
typename k,
typename v>
441bool con_set<k, v>::keyExists(
const k& key)
445 for (entry = table; entry != NULL; entry = entry->next) {
446 if (entry->GetKey() == key) {
454template<
typename key,
typename value>
455unsigned int con_set<key, value>::size()
460template<
typename key,
typename value>
466 using Entry =
typename con_set<key, value>::Entry;
470 unsigned int m_Index;
471 Entry *m_CurrentEntry;
480 Entry *NextElement(
void);
481 Entry *CurrentElement(
void);
484template<
typename key,
typename value>
485con_set_enum<key, value>::con_set_enum()
489 m_CurrentEntry = NULL;
493template<
typename key,
typename value>
499template<
typename key,
typename value>
503 m_Index = m_Set->tableLength;
504 m_CurrentEntry = NULL;
510template<
typename key,
typename value>
511typename con_set_enum<key, value>::Entry *con_set_enum<key, value>::CurrentElement(
void)
513 return m_CurrentEntry;
516template<
typename key,
typename value>
517typename con_set_enum<key, value>::Entry *con_set_enum<key, value>::NextElement(
void)
526 m_NextEntry = m_Set->table[m_Index];
534 m_CurrentEntry = NULL;
539 m_CurrentEntry = m_NextEntry;
540 m_NextEntry = m_NextEntry->next;
542 return m_CurrentEntry;
545template<
typename key,
typename value>
554#ifdef ARCHIVE_SUPPORTED
559 virtual void resize(
int count = 0);
561 value& operator[](
const key& index);
563 value *find(
const key& index);
564 bool remove(
const key& index);
569template<
typename key,
typename value>
570void con_map<key, value>::clear()
575template<
typename key,
typename value>
576void con_map<key, value>::resize(
int count)
578 m_con_set.resize(count);
581template<
typename key,
typename value>
582value& con_map<key, value>::operator[](
const key& index)
584 return m_con_set.addKeyValue(index);
587template<
typename key,
typename value>
588value *con_map<key, value>::find(
const key& index)
590 return m_con_set.findKeyValue(index);
593template<
typename key,
typename value>
594bool con_map<key, value>::remove(
const key& index)
596 return m_con_set.remove(index);
599template<
typename key,
typename value>
600unsigned int con_map<key, value>::size(
void)
602 return m_con_set.size();
605template<
typename key,
typename value>
609 using Entry =
typename con_set_enum<key, value>::Entry;
621 value *NextValue(
void);
622 key *CurrentKey(
void);
623 value *CurrentValue(
void);
626template<
typename key,
typename value>
627con_map_enum<key, value>::con_map_enum()
629 m_Set_Enum.m_Set = NULL;
630 m_Set_Enum.m_Index = 0;
631 m_Set_Enum.m_CurrentEntry = NULL;
632 m_Set_Enum.m_NextEntry = NULL;
635template<
typename key,
typename value>
641template<
typename key,
typename value>
644 m_Set_Enum = map.m_con_set;
649template<
typename key,
typename value>
650key *con_map_enum<key, value>::CurrentKey(
void)
652 Entry *entry = m_Set_Enum.CurrentElement();
655 return &entry->GetKey();
661template<
typename key,
typename value>
662value *con_map_enum<key, value>::CurrentValue(
void)
664 Entry *entry = m_Set_Enum.CurrentElement();
667 return &entry->value;
673template<
typename key,
typename value>
674key *con_map_enum<key, value>::NextKey(
void)
676 Entry *entry = m_Set_Enum.NextElement();
679 return &entry->GetKey();
685template<
typename key,
typename value>
686value *con_map_enum<key, value>::NextValue(
void)
688 Entry *entry = m_Set_Enum.NextElement();
691 return &entry->value;
Definition mem_blockalloc.h:172