4
4
using System . Collections ;
5
5
using System . IO ;
6
6
using System . Runtime . InteropServices ;
7
+ using System . Collections . Generic ;
7
8
8
9
using UnityEngine ;
9
10
@@ -24,19 +25,13 @@ public static class Bindings
24
25
// Holds objects and provides handles to them in the form of ints
25
26
public static class ObjectStore
26
27
{
28
+ static Dictionary < uint , int > handleLookupByHash ;
29
+ static Dictionary < int , uint > hashLookupByHandle ;
30
+ static Stack < int > freeHandleStack ;
31
+
27
32
// Stored objects. The first is never used so 0 can be "null".
28
33
static object [ ] objects ;
29
34
30
- // Stack of available handles
31
- static int [ ] handles ;
32
-
33
- // Hash table of stored objects to their handles.
34
- static object [ ] keys ;
35
- static int [ ] values ;
36
-
37
- // Index of the next available handle
38
- static int nextHandleIndex ;
39
-
40
35
// The maximum number of objects to store. Must be positive.
41
36
static int maxObjects ;
42
37
@@ -49,19 +44,13 @@ public static void Init(int maxObjects)
49
44
objects = new object [ maxObjects + 1 ] ;
50
45
51
46
// Initialize the handles stack as 1, 2, 3, ...
52
- handles = new int [ maxObjects ] ;
53
47
for (
54
48
int i = 0 , handle = maxObjects ;
55
49
i < maxObjects ;
56
50
++ i , -- handle )
57
51
{
58
- handles [ i ] = handle ;
52
+ freeHandleStack . Push ( handle ) ;
59
53
}
60
- nextHandleIndex = maxObjects - 1 ;
61
-
62
- // Initialize the hash table
63
- keys = new object [ maxObjects ] ;
64
- values = new int [ maxObjects ] ;
65
54
}
66
55
67
56
public static int Store ( object obj )
@@ -75,27 +64,15 @@ public static int Store(object obj)
75
64
lock ( objects )
76
65
{
77
66
// Pop a handle off the stack
78
- int handle = handles [ nextHandleIndex ] ;
79
- nextHandleIndex -- ;
67
+ int handle = freeHandleStack . Pop ( ) ;
80
68
81
69
// Store the object
82
70
objects [ handle ] = obj ;
83
71
84
72
// Insert into the hash table
85
- int initialIndex = ( int ) (
86
- ( ( uint ) obj . GetHashCode ( ) ) % maxObjects ) ;
87
- int index = initialIndex ;
88
- do
89
- {
90
- if ( object . ReferenceEquals ( keys [ index ] , null ) )
91
- {
92
- keys [ index ] = obj ;
93
- values [ index ] = handle ;
94
- break ;
95
- }
96
- index = ( index + 1 ) % maxObjects ;
97
- }
98
- while ( index != initialIndex ) ;
73
+ uint hash = ( uint ) obj . GetHashCode ( ) ;
74
+ handleLookupByHash . Add ( hash , handle ) ;
75
+ hashLookupByHandle . Add ( handle , hash ) ;
99
76
100
77
return handle ;
101
78
}
@@ -108,6 +85,7 @@ public static object Get(int handle)
108
85
109
86
public static int GetHandle ( object obj )
110
87
{
88
+
111
89
// Null is always zero
112
90
if ( object . ReferenceEquals ( obj , null ) )
113
91
{
@@ -116,19 +94,12 @@ public static int GetHandle(object obj)
116
94
117
95
lock ( objects )
118
96
{
119
- // Look up the object in the hash table
120
- int initialIndex = ( int ) (
121
- ( ( uint ) obj . GetHashCode ( ) ) % maxObjects ) ;
122
- int index = initialIndex ;
123
- do
97
+ // Look up the handle in the hash table
98
+ uint hash = ( uint ) obj . GetHashCode ( ) ;
99
+ if ( handleLookupByHash . ContainsKey ( hash ) )
124
100
{
125
- if ( object . ReferenceEquals ( keys [ index ] , obj ) )
126
- {
127
- return values [ index ] ;
128
- }
129
- index = ( index + 1 ) % maxObjects ;
101
+ return handleLookupByHash [ hash ] ;
130
102
}
131
- while ( index != initialIndex ) ;
132
103
}
133
104
134
105
// Object not found
@@ -150,28 +121,12 @@ public static object Remove(int handle)
150
121
objects [ handle ] = null ;
151
122
152
123
// Push the handle onto the stack
153
- nextHandleIndex ++ ;
154
- handles [ nextHandleIndex ] = handle ;
124
+ freeHandleStack . Push ( handle ) ;
155
125
156
- // Remove the object from the hash table
157
- int initialIndex = ( int ) (
158
- ( ( uint ) obj . GetHashCode ( ) ) % maxObjects ) ;
159
- int index = initialIndex ;
160
- do
161
- {
162
- if ( object . ReferenceEquals ( keys [ index ] , obj ) )
163
- {
164
- // Only the key needs to be removed (set to null)
165
- // because values corresponding to null will never
166
- // be read and the values are just integers, so
167
- // we're not holding on to a managed reference that
168
- // will prevent GC.
169
- keys [ index ] = null ;
170
- break ;
171
- }
172
- index = ( index + 1 ) % maxObjects ;
173
- }
174
- while ( index != initialIndex ) ;
126
+ // Remove the object from the hash dictionary's
127
+ var hash = hashLookupByHandle [ handle ] ;
128
+ handleLookupByHash . Remove ( hash ) ;
129
+ hashLookupByHandle . Remove ( handle ) ;
175
130
176
131
return obj ;
177
132
}
0 commit comments