44using System . Collections ;
55using System . IO ;
66using System . Runtime . InteropServices ;
7+ using System . Collections . Generic ;
78
89using UnityEngine ;
910
@@ -24,19 +25,13 @@ public static class Bindings
2425 // Holds objects and provides handles to them in the form of ints
2526 public static class ObjectStore
2627 {
28+ static Dictionary < uint , int > handleLookupByHash ;
29+ static Dictionary < int , uint > hashLookupByHandle ;
30+ static Stack < int > freeHandleStack ;
31+
2732 // Stored objects. The first is never used so 0 can be "null".
2833 static object [ ] objects ;
2934
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-
4035 // The maximum number of objects to store. Must be positive.
4136 static int maxObjects ;
4237
@@ -49,19 +44,13 @@ public static void Init(int maxObjects)
4944 objects = new object [ maxObjects + 1 ] ;
5045
5146 // Initialize the handles stack as 1, 2, 3, ...
52- handles = new int [ maxObjects ] ;
5347 for (
5448 int i = 0 , handle = maxObjects ;
5549 i < maxObjects ;
5650 ++ i , -- handle )
5751 {
58- handles [ i ] = handle ;
52+ freeHandleStack . Push ( handle ) ;
5953 }
60- nextHandleIndex = maxObjects - 1 ;
61-
62- // Initialize the hash table
63- keys = new object [ maxObjects ] ;
64- values = new int [ maxObjects ] ;
6554 }
6655
6756 public static int Store ( object obj )
@@ -75,27 +64,15 @@ public static int Store(object obj)
7564 lock ( objects )
7665 {
7766 // Pop a handle off the stack
78- int handle = handles [ nextHandleIndex ] ;
79- nextHandleIndex -- ;
67+ int handle = freeHandleStack . Pop ( ) ;
8068
8169 // Store the object
8270 objects [ handle ] = obj ;
8371
8472 // 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 ) ;
9976
10077 return handle ;
10178 }
@@ -108,6 +85,7 @@ public static object Get(int handle)
10885
10986 public static int GetHandle ( object obj )
11087 {
88+
11189 // Null is always zero
11290 if ( object . ReferenceEquals ( obj , null ) )
11391 {
@@ -116,19 +94,12 @@ public static int GetHandle(object obj)
11694
11795 lock ( objects )
11896 {
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 ) )
124100 {
125- if ( object . ReferenceEquals ( keys [ index ] , obj ) )
126- {
127- return values [ index ] ;
128- }
129- index = ( index + 1 ) % maxObjects ;
101+ return handleLookupByHash [ hash ] ;
130102 }
131- while ( index != initialIndex ) ;
132103 }
133104
134105 // Object not found
@@ -150,28 +121,12 @@ public static object Remove(int handle)
150121 objects [ handle ] = null ;
151122
152123 // Push the handle onto the stack
153- nextHandleIndex ++ ;
154- handles [ nextHandleIndex ] = handle ;
124+ freeHandleStack . Push ( handle ) ;
155125
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 ) ;
175130
176131 return obj ;
177132 }
0 commit comments