aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.Client/PSVita/PSVitaExtras/CustomSet.cpp
blob: 4b96f1aa78e9b4361a7d6ecc384bc3672cce1d37 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include "stdafx.h"
#include "CustomSet.h"


CustomSet::CustomSet()
{
	m_NodePool = nullptr;
	m_NodePoolSize = 0;
	m_NodePoolIndex = 0;

	m_HashSize = 1024;
	m_HashTable = static_cast<SCustomSetNode **>(malloc(m_HashSize * sizeof(SCustomSetNode)));

	clear();
}

CustomSet::~CustomSet()
{
	for( int i = 0;i < m_NodePoolSize; i += 1 )
	{
		free(m_NodePool[i]);
	}
	free(m_NodePool);

	free(m_HashTable);
}

void CustomSet::clear()
{
	// reset the pool index
	m_NodePoolIndex = 0;

	// clear the hash table
	memset(m_HashTable, 0, m_HashSize * sizeof(SCustomSetNode));
}

SCustomSetNode* CustomSet::find(const ChunkPos &Key)
{
	unsigned int Hash = (Key.x & 0x00000001f) | (Key.z << 5);	// hopefully this will produce a good hash for a 1024 entry table
	unsigned int Index = Hash & (m_HashSize-1);

	SCustomSetNode* Node = m_HashTable[Index];
	while( Node && Node->Hash != Hash )
	{
		Node = Node->Next;
	}

	return Node;
}

int CustomSet::end()
{
	return m_NodePoolIndex;
}

ChunkPos CustomSet::get(int index)
{
	return m_NodePool[index]->key;
}

void CustomSet::insert(const ChunkPos &Key)
{
	// see if this key already exists
	SCustomSetNode* Node = find(Key);

	if( !Node )
	{
		// do we have any space in the pool
		if( m_NodePoolIndex >= m_NodePoolSize )
		{
			resize();
		}

		// grab the next node from the pool
		Node = m_NodePool[m_NodePoolIndex];
		m_NodePoolIndex++;
	}
	else
	{
		return;
	}

	// create the new node;
	unsigned int Hash = (Key.x & 0x00000001f) | (Key.z << 5);	// hopefully this will produce a good hash for a 1024 entry table
	unsigned int Index = Hash & (m_HashSize-1);
	Node->Hash = Hash;
	Node->key = Key;
	Node->Next = nullptr;

	// are any nodes in this hash index
	if( !m_HashTable[Index] )
	{
		m_HashTable[Index] = Node;
	}
	else
	{
		// loop to the last node in the hash list
		SCustomSetNode* OldNode = m_HashTable[Index];
		while( OldNode->Next )
		{
			OldNode = OldNode->Next;
		}

		// link the old last node to the new one
		OldNode->Next = Node;
	}
}

void CustomSet::resize()
{
	int OldPoolSize = m_NodePoolSize;
	m_NodePoolSize += 512;
	SCustomSetNode **NodePool;
	if( m_NodePool )
	{
		NodePool = static_cast<SCustomSetNode **>(realloc(m_NodePool, m_NodePoolSize * sizeof(SCustomSetNode)));
	}
	else
	{
		NodePool = static_cast<SCustomSetNode **>(malloc(m_NodePoolSize * sizeof(SCustomSetNode)));
	}

	for( int i = 0;i < m_NodePoolSize - OldPoolSize;i += 1 )
	{
		NodePool[i + OldPoolSize] = static_cast<SCustomSetNode *>(malloc(sizeof(SCustomSetNode)));
	}

	m_NodePool = NodePool;
}