1#ifndef CCOLLECTION_CLASS_H
2#define CCOLLECTION_CLASS_H
8#include "OffsetArray.h"
10BEGIN_MOOTOOLS_NAMESPACE
14 #define COLLECTION_STATS
28 template<
class DATATYPE,
class SIZETYPE>
35 int entryIndex, elementsSize;
46 int GetEntryIndex()
const;
49 const DATATYPE *GetData(
int& size)
const;
64 template<
class DATATYPE,
class SIZETYPE>
67 elementCollection =
NULL;
69 elementsSize = entryIndex = 0;
72 template<
class DATATYPE,
class SIZETYPE>
78 elementData = size > 0 ? data :
NULL;
81 template<
class DATATYPE,
class SIZETYPE>
84 elementCollection =
NULL;
86 elementsSize = entryIndex = 0;
89 template<
class DATATYPE,
class SIZETYPE>
92 return (elementsSize == 0) || (elementData ==
NULL);
95 template<
class DATATYPE,
class SIZETYPE>
101 template<
class DATATYPE,
class SIZETYPE>
107 template<
class DATATYPE,
class SIZETYPE>
110 size = this->elementsSize;
114 template<
class DATATYPE,
class SIZETYPE>
117 size = this->elementsSize;
121 template<
class DATATYPE,
class SIZETYPE>
124 if (
i < elementsSize)
125 return elementData[
i];
128 return elementData[0];
131 template<
class DATATYPE,
class SIZETYPE>
134 if (
i < elementsSize)
135 return elementData[
i];
138 return elementData[0];
141 template<
class DATATYPE,
class SIZETYPE>
144 if (
i < elementsSize)
146 elementData[
i] = type;
153 template<
class DATATYPE,
class SIZETYPE>
156 XASSERT(elementCollection);
160 elementCollection->GetEntry(entryIndex,
tmp);
161 XASSERT(
tmp == elementsSize);
164 elementData = elementCollection->SetEntrySize(entryIndex, elementsSize++);
165 elementData[elementsSize] = type;
170 template<
class DATATYPE,
class SIZETYPE>
173 XASSERT(elementCollection);
174 elementData = elementCollection->SetEntry(entryIndex,
copy);
175 elementsSize =
copy.GetSize();
178 template<
class DATATYPE,
class SIZETYPE>
181 XASSERT(elementCollection);
182 elementCollection->SetEntry(entryIndex,
srcindex);
183 elementData = elementCollection->GetEntry(entryIndex, elementsSize);
186 template<
class DATATYPE,
class SIZETYPE>
189 XASSERT(elementCollection);
190 if (index < elementsSize)
192 elementsSize = elementCollection->RemoveElementInEntry(entryIndex, index);
199 template<
class DATATYPE,
class SIZETYPE>
202 XASSERT(elementCollection);
206 elementData = elementCollection->SetEntrySize(entryIndex,
newsize);
221 typedef enum _CollectionInitializeMode
223 COL_EMPTY_NEW_ENTRIES = 0x01,
224 COL_EMPTY_COLLECTION = 0x02,
225 COL_KEEP_ENTRIES = 0x04,
226 COL_SHRINK_ENTRIES = 0x08,
227 COL_GROWING_ENTRIES = 0x10,
228 COL_EXACTSIZE_ENTRIES = 0x20,
232 typedef enum _CollectionElementsMode
234 COL_CREATE_ELEMENTS = 0x01,
236 } _CollectionElementsMode;
238 typedef struct CSCOffsetRange
242 unsigned int start, end;
245 template<
class TYPE,
class SIZETYPE>
251 struct CElementHeader
259 unsigned int entriesNbr;
261 SIZET dataOffset, dataSize;
262 COffsetArray offsetArray;
264 #ifdef COLLECTION_STATS
276 TYPE *InitElementsSize(
unsigned int index,
unsigned int size,
unsigned int creationMode);
286 virtual void DestroyEntries(
unsigned int first,
unsigned int number);
287 virtual void CreateEntries(
unsigned int first,
unsigned int number);
295 unsigned int GetDefaultEntrySize() {
return defaultElementsNbr; };
302 unsigned int GetEntriesSize()
const;
303 unsigned int *GetSizes(
unsigned int& size)
const;
304 void SetEntriesSize(
unsigned int entriesNbr,
unsigned int defaultElementsNbr,
unsigned int mode,
unsigned int *elementsSize =
NULL);
315 TYPE *GetEntry(
unsigned int index,
int& size)
const;
316 void RemoveEntry(
unsigned int index,
unsigned int nCount = 1);
323 unsigned int RemoveElementInEntry(
unsigned int index,
unsigned elementIndex);
330 #define COL_TYPE_PTR(data, offset) ((TYPE *)((unsigned char *)data+offset+sizeof(typename CSimpleCollection<TYPE, SIZETYPE>::CElementHeader)))
331 #define COL_HEADER_PTR(data, offset) ((typename CSimpleCollection<TYPE, SIZETYPE>::CElementHeader *)((unsigned char *)data+offset))
332 #define COL_DATA_SIZE(elementnbr) ((SIZET)((elementnbr)*sizeof(TYPE)+sizeof(typename CSimpleCollection<TYPE, SIZETYPE>::CElementHeader)))
337 template<
class TYPE,
class SIZETYPE>
344 this->defaultElementsNbr = 3;
349 template<
class TYPE,
class SIZETYPE>
356 template<
class TYPE,
class SIZETYPE>
360 unsigned int count = 0;
363 for (
unsigned int i=0;
i<entriesNbr;
i++)
365 offset = offsetArray[
i];
366 header = COL_HEADER_PTR(data, offset);
369 #ifdef COLLECTION_STATS
377 #ifdef COLLECTION_STATS
378 template<
class TYPE,
class SIZETYPE>
383 unsigned int i,
elements = 0, totalsize = 0;
386 for (
i=0;
i<entriesNbr;
i++)
388 offset = offsetArray[
i];
390 header = COL_HEADER_PTR(data, offset);
391 totalsize += COL_DATA_SIZE(
header->size);
402 SIZET totalsize = (
curElements*
sizeof(
TYPE)+entriesNbr*
sizeof(CElementHeader));
416 template<
class TYPE,
class SIZETYPE>
419 #ifdef COLLECTION_STATS
425 template<
class TYPE,
class SIZETYPE>
428 #ifdef COLLECTION_STATS
435 offset = offsetArray[
i];
436 header = COL_HEADER_PTR(data, offset);
443 template<
class TYPE,
class SIZETYPE>
446 #ifdef COLLECTION_STATS
453 template<
class TYPE,
class SIZETYPE>
456 #ifdef COLLECTION_STATS
463 offset = offsetArray[
i];
464 header = COL_HEADER_PTR(data, offset);
470 template<
class TYPE,
class SIZETYPE>
476 template<
class TYPE,
class SIZETYPE>
494 template<
class TYPE,
class SIZETYPE>
502 offsetArray.RemoveAll();
504 #ifdef COLLECTION_STATS
513 template<
class TYPE,
class SIZETYPE>
519 XASSERT(!entriesNbr);
520 XASSERT(!offsetArray.GetSize());
524 #ifdef COLLECTION_STATS
527 XTRACE(
traceStruct, 0,
"CSimpleCollection (current size: %d - element size: %d)\n", dataSize,
sizeof(
TYPE));
535 DestroyEntries(0, entriesNbr);
537 #ifdef COLLECTION_STATS
541 xDeallocateArray(data);
548 template<
class TYPE,
class SIZETYPE>
554 defaultElementsNbr =
collection.defaultElementsNbr;
567 size += COL_DATA_SIZE(
srcheader->maxsize);
576 offsetArray.SetSize(entriesNbr);
584 dstheader = COL_HEADER_PTR(data, dataOffset);
588 dataOffset += COL_DATA_SIZE(
srcheader->maxsize);
607 #ifdef COLLECTION_STATS
612 template<
class TYPE,
class SIZETYPE>
627 ar.Write(data,
static_cast<unsigned int>(dataSize*
sizeof(
unsigned char)));
628 offsetArray.Serialize(
ar);
640 dataOffset = (SIZET)
tmp;
643 dataSize = (SIZET)
tmp;
645 data = xAllocateArray(
unsigned char, dataSize);
646 ar.Read(data,
static_cast<unsigned int>(dataSize*
sizeof(
unsigned char)));
647 offsetArray.Serialize(
ar);
649 #ifdef COLLECTION_STATS
656#ifdef SC_REUSED_MEMORY
657static int rangeCompareProc(
const void *
elem1,
const void *
elem2)
659 if (((
const CSCOffsetRange *)
elem1)->offset == ((
const CSCOffsetRange *)
elem2)->offset)
662 return ((
const CSCOffsetRange *)
elem1)->offset > ((
const CSCOffsetRange *)
elem2)->offset ? 1 : -1;
667 template<
class TYPE,
class SIZETYPE>
672 xDeallocateArray(data);
676 offsetArray.SetSize(0);
680 #ifdef SC_REUSED_MEMORY
685 CSCOffsetRange
range;
692 else if (
i > entriesNbr*0.01f)
693 i = (
unsigned int)(entriesNbr*0.01f);
694 ranges.SetSize(
i, (entriesNbr*0.01f) < 1024 ? -1 : (
INT_PTR)(entriesNbr*0.01f));
697 SIZET offset = offsetArray[0];
698 header = COL_HEADER_PTR(data, offset);
701 range.offset = offsetArray[0];
705 for (
i=1;
i<entriesNbr;
i++)
707 offset = offsetArray[
i];
708 header = COL_HEADER_PTR(data, offset);
719 range.offset = offset;
726 range.end = entriesNbr;
743 offsetArray[
j] = offsetArray[
j]-
delta;
750 offsetArray.SetSize(entriesNbr);
752 XASSERT(dataOffset == GetDataSize());
754 #ifdef COLLECTION_STATS
766 for (
unsigned int i=0;
i<entriesNbr;
i++)
768 offset = offsetArray[
i];
771 oldheader = COL_HEADER_PTR(data, offset);
778 offset +=
sizeof(CElementHeader);
788 xDeallocateArray(data);
793 offsetArray.SetSize(entriesNbr);
794 offsetArray.FreeExtra();
796 #ifdef COLLECTION_STATS
801 template<
class TYPE,
class SIZETYPE>
808 SIZET offset, totalsize = 0;
814 for (
i=0;
i<entriesNbr;
i++)
816 offset = offsetArray[
i];
817 header = COL_HEADER_PTR(data, offset);
818 totalsize += COL_DATA_SIZE(
header->maxsize);
823 for (
i=0;
i<entriesNbr;
i++)
825 offset = offsetArray[
i];
826 header = COL_HEADER_PTR(data, offset);
827 totalsize += COL_DATA_SIZE(
header->size);
835 template<
class TYPE,
class SIZETYPE>
849 template<
class TYPE,
class SIZETYPE>
868 template<
class TYPE,
class SIZETYPE>
886 template<
class TYPE,
class SIZETYPE>
904 #ifdef COLLECTION_STATS
912 xDeallocateArray(data);
917 #ifdef COLLECTION_STATS
922 template<
class TYPE,
class SIZETYPE>
929 if (!
elements || (mode & COL_EMPTY_COLLECTION))
931 if (!(mode & COL_GROWING_ENTRIES))
939 SIZETYPE headerSizeNbr = (mode & (COL_EMPTY_NEW_ENTRIES|COL_EMPTY_COLLECTION)) ? 0 : defaultElementsNbr;
947 XASSERT(elementsSize[
i] <= (
SIZETYPE)(-1));
948 newSize += COL_DATA_SIZE(elementsSize[
i]);
961 header = COL_HEADER_PTR(data, dataOffset);
963 offsetArray.SetAt(
i, dataOffset);
968 header->maxsize = defaultElementsNbr;
970 dataOffset += COL_DATA_SIZE(
header->maxsize);
973 if (defaultElementsNbr)
976 if (mode & COL_EMPTY_COLLECTION)
983 XASSERT(!elementsSize);
984 XASSERT(mode & (COL_KEEP_ENTRIES|COL_SHRINK_ENTRIES));
985 XASSERT(!(mode & COL_EMPTY_COLLECTION));
997 if (mode & COL_KEEP_ENTRIES)
1001 newSize = dataOffset+COL_DATA_SIZE(defaultElementsNbr)*(
elements-entriesNbr);
1013 SIZET offset = offsetArray[
i];
1014 header = COL_HEADER_PTR(data, offset);
1018 newSize -= COL_DATA_SIZE(defaultElementsNbr);
1023 Grow(
newSize, (mode & COL_EXACTSIZE_ENTRIES) ?
false :
true);
1031 for (
unsigned int i = entriesNbr;
i<
elements;
i++)
1033 header = COL_HEADER_PTR(data, dataOffset);
1034 offsetArray.SetAt(
i, dataOffset);
1036 header->maxsize = defaultElementsNbr;
1037 dataOffset += COL_DATA_SIZE(
header->maxsize);
1041 if (defaultElementsNbr)
1042 CreateEntries(entriesNbr,
elements-entriesNbr);
1044 if (mode & COL_SHRINK_ENTRIES)
1049 for (
unsigned int i=0;
i<entriesNbr;
i++)
1050 InitElementsSize(
i, defaultElementsNbr, (mode & COL_EMPTY_NEW_ENTRIES) ? 0 : COL_CREATE_ELEMENTS);
1060 if (mode & COL_GROWING_ENTRIES)
1067 if (mode & COL_SHRINK_ENTRIES)
1069 XASSERT(!(mode & COL_EMPTY_NEW_ENTRIES));
1073 InitElementsSize(
i, defaultElementsNbr, (mode & COL_EMPTY_NEW_ENTRIES) ? 0 : COL_CREATE_ELEMENTS);
1079 if (mode & COL_GROWING_ENTRIES)
1083 FreeExtra(!(mode & COL_EXACTSIZE_ENTRIES));
1086 #ifdef COLLECTION_STATS
1091 template<
class TYPE,
class SIZETYPE>
1094 if (index < entriesNbr)
1099 SIZET offset = offsetArray[index];
1100 CElementHeader *
header = COL_HEADER_PTR(data, offset);
1101 DestroyElement(COL_TYPE_PTR(data, offset),
header->size);
1102 offsetArray.RemoveAt(index);
1106 if (
nCount > 0 && index == entriesNbr)
1113 #ifdef COLLECTION_STATS
1123 template<
class TYPE,
class SIZETYPE>
1129 template<
class TYPE,
class SIZETYPE>
1133 unsigned int *
sizes = xAllocateArray(
unsigned int, size);
1136 for (
int i=0;
i<size;
i++)
1138 header = COL_HEADER_PTR(data, offsetArray[
i]);
1145 template<
class TYPE,
class SIZETYPE>
1148 if (index < entriesNbr)
1154 XASSERT(
element.elementCollection);
1155 if (
element.elementCollection ==
this)
1160 elementData =
element.elementCollection->GetEntry(
element.entryIndex, size);
1161 XASSERT(size ==
element.GetSize());
1173 template<
class TYPE,
class SIZETYPE>
1180 XASSERT(((
void *)
entrydata < (
void *)data) || ((
void *)
entrydata > (
void *)(data+dataSize)));
1191 template<
class TYPE,
class SIZETYPE>
1212 template<
class TYPE,
class SIZETYPE>
1215 if (index < entriesNbr)
1217 SIZET offset = offsetArray[index];
1218 type.Init(
this, index, COL_HEADER_PTR(data, offset)->size, COL_TYPE_PTR(data, offset));
1222 type.Init(
this, index, 0,
NULL);
1226 template<
class TYPE,
class SIZETYPE>
1229 if (index < entriesNbr)
1231 SIZET offset = offsetArray[index];
1240 template<
class TYPE,
class SIZETYPE>
1243 if (index < entriesNbr)
1245 SIZET offset = offsetArray[index];
1246 size = COL_HEADER_PTR(data, offset)->size;
1250 return COL_TYPE_PTR(data, offset);
1258 template<
class TYPE,
class SIZETYPE>
1261 XASSERT(size <= 0xFFFF);
1262 if (index < entriesNbr)
1264 SIZET offset = offsetArray[index];
1266 CElementHeader *
header = COL_HEADER_PTR(data, offset);
1267 unsigned int cursize =
header->size;
1269 if (size == cursize)
1270 return COL_TYPE_PTR(data, offset);
1271 else if (size < cursize)
1278 DestroyElement(
element, cursize-size);
1280 return COL_TYPE_PTR(data, offset);
1285 if ((creationMode & COL_CREATE_ELEMENTS))
1292 CreateElement(
element, size-cursize);
1295 return COL_TYPE_PTR(data, offset);
1303 if (offset + COL_DATA_SIZE(
header->maxsize) == dataOffset)
1305 Grow(offset + COL_DATA_SIZE(size));
1307 header = COL_HEADER_PTR(data, offset);
1308 header->size = (
SIZETYPE)((creationMode & COL_CREATE_ELEMENTS) ? size : cursize);
1312 if ((creationMode & COL_CREATE_ELEMENTS))
1316 CreateElement(
element, size - cursize);
1319 dataOffset = offset + COL_DATA_SIZE(size);
1321 return COL_TYPE_PTR(data, offset);
1325 if ((creationMode & COL_COMPRESS) && ((dataOffset+COL_DATA_SIZE(size)) > dataSize))
1329 Grow(dataOffset+COL_DATA_SIZE(size));
1331 offsetArray.SetAt(index, dataOffset);
1332 header = COL_HEADER_PTR(data, dataOffset);
1333 header->size = (
SIZETYPE)((creationMode & COL_CREATE_ELEMENTS) ? size : cursize);
1337 dataOffset +=
sizeof(CElementHeader);
1338 xmemcpy_s(data+dataOffset, dataSize-dataOffset, COL_TYPE_PTR(data, offset), cursize*
sizeof(
TYPE));
1339 dataOffset += cursize*
sizeof(
TYPE);
1342 if ((creationMode & COL_CREATE_ELEMENTS))
1343 CreateElement((
TYPE *)(data+dataOffset), size-cursize);
1345 #ifdef COLLECTION_STATS
1350 dataOffset += (size-cursize)*
sizeof(
TYPE);
1352 return COL_TYPE_PTR(data, offsetArray[index]);
1359 template<
class TYPE,
class SIZETYPE>
1362 return InitElementsSize(index, size,
createElements ? COL_CREATE_ELEMENTS : 0);
1365 template<
class TYPE,
class SIZETYPE>
1368 return InitElementsSize(index, size,
createElements ? COL_CREATE_ELEMENTS|COL_COMPRESS : COL_COMPRESS);
1371 template<
class TYPE,
class SIZETYPE>
1374 unsigned int entryIndex = AddEntry(
true,
element.GetSize());
1375 SetEntry(entryIndex,
element);
1380 template<
class TYPE,
class SIZETYPE>
1387 if (entriesNbr < (
unsigned int)offsetArray.GetSize())
1395 offsetArray.SetAtGrow(entriesNbr++, dataOffset);
1397 CElementHeader *
header = COL_HEADER_PTR(data, dataOffset);
1401 dataOffset +=
sizeof(CElementHeader);
1409 return entriesNbr-1;
1412 template<
class TYPE,
class SIZETYPE>
1415 if (index < entriesNbr)
1417 SIZET offset = offsetArray[index];
1418 CElementHeader *
header = COL_HEADER_PTR(data, offset);
1456 template<
class TYPE,
class SIZETYPE>
1459 if (index < entriesNbr)
1461 SIZET offset = offsetArray[index];
1462 CElementHeader *
header = COL_HEADER_PTR(data, offset);
1494 template<
class TYPE,
class SIZETYPE>
1502 virtual void DestroyEntries(
unsigned int first,
unsigned int number);
1503 virtual void CreateEntries(
unsigned int first,
unsigned int number);
1514 template<
class TYPE,
class SIZETYPE>
1520 template<
class TYPE,
class SIZETYPE>
1527 template<
class TYPE,
class SIZETYPE>
1530 #ifdef COLLECTION_STATS
1542 template<
class TYPE,
class SIZETYPE>
1551 offset = this->offsetArray[
i];
1552 header = COL_HEADER_PTR(this->data, offset);
1554 DestroyElement(COL_TYPE_PTR(this->data, offset),
header->size);
1559 template<
class TYPE,
class SIZETYPE>
1562 #ifdef COLLECTION_STATS
1569 #pragma push_macro("new")
1572 #pragma pop_macro("new")
1578 template<
class TYPE,
class SIZETYPE>
1587 offset = this->offsetArray[
i];
1588 header = COL_HEADER_PTR(this->data, offset);
1590 CreateElement(COL_TYPE_PTR(this->data, offset),
header->size);
1594 template<
class TYPE,
class SIZETYPE>
1604 template<
class TYPE,
class SIZETYPE>
1633END_MOOTOOLS_NAMESPACE
The class defines an x, y, z 3D point which can use int, float or double.
Definition 3DPoint.h:27
Definition Collection.h:30
Definition Collection.h:1496
Definition Collection.h:247