@@ -25,9 +25,10 @@ public static class Bindings
2525 // Holds objects and provides handles to them in the form of ints
2626 public static class ObjectStore
2727 {
28- static Dictionary < uint , int > handleLookupByHash ;
28+ static Dictionary < uint , List < int > > handleBucketByHash ;
2929 static Dictionary < int , uint > hashLookupByHandle ;
30- static Stack < int > freeHandleStack ;
30+ static HashSet < int > hash ;
31+ static Stack < int > handles ;
3132
3233 // Stored objects. The first is never used so 0 can be "null".
3334 static object [ ] objects ;
@@ -38,9 +39,9 @@ public static class ObjectStore
3839 public static void Init ( int maxObjects )
3940 {
4041 ObjectStore . maxObjects = maxObjects ;
41- handleLookupByHash = new Dictionary < uint , int > ( ) ;
42+ handleBucketByHash = new Dictionary < uint , List < int > > ( ) ;
4243 hashLookupByHandle = new Dictionary < int , uint > ( ) ;
43- freeHandleStack = new Stack < int > ( ) ;
44+ handles = new Stack < int > ( ) ;
4445
4546 // Initialize the objects as all null plus room for the
4647 // first to always be null.
@@ -52,7 +53,7 @@ public static void Init(int maxObjects)
5253 i < maxObjects ;
5354 ++ i , -- handle )
5455 {
55- freeHandleStack . Push ( handle ) ;
56+ handles . Push ( handle ) ;
5657 }
5758 }
5859
@@ -66,16 +67,28 @@ public static int Store(object obj)
6667
6768 lock ( objects )
6869 {
70+ // Get the hash of the object
71+ uint hash = ( uint ) obj . GetHashCode ( ) ;
72+
6973 // Pop a handle off the stack
70- int handle = freeHandleStack . Pop ( ) ;
74+ int handle = handles . Pop ( ) ;
7175
7276 // Store the object
7377 objects [ handle ] = obj ;
74-
75- // Insert into the hash table
76- uint hash = ( uint ) obj . GetHashCode ( ) ;
77- handleLookupByHash . Add ( hash , handle ) ;
78- hashLookupByHandle . Add ( handle , hash ) ;
78+
79+ List < int > handleBucket = null ;
80+
81+ // Create new handle bucket if it does not exist
82+ if ( ! handleBucketByHash . TryGetValue ( hash , out handleBucket ) )
83+ {
84+ handleBucket = new List < int > ( ) ;
85+ handleBucketByHash [ hash ] = handleBucket ;
86+ }
87+
88+ // Insert into hash table
89+ handleBucket . Add ( handle ) ;
90+
91+ hashLookupByHandle [ handle ] = hash ;
7992
8093 return handle ;
8194 }
@@ -88,7 +101,6 @@ public static object Get(int handle)
88101
89102 public static int GetHandle ( object obj )
90103 {
91-
92104 // Null is always zero
93105 if ( object . ReferenceEquals ( obj , null ) )
94106 {
@@ -99,9 +111,20 @@ public static int GetHandle(object obj)
99111 {
100112 // Look up the handle in the hash table
101113 uint hash = ( uint ) obj . GetHashCode ( ) ;
102- if ( handleLookupByHash . ContainsKey ( hash ) )
114+ List < int > handleBucket = null ;
115+
116+ if ( handleBucketByHash . TryGetValue ( hash , out handleBucket ) )
103117 {
104- return handleLookupByHash [ hash ] ;
118+ for ( int i = 0 ; i < handleBucket . Count ; i ++ )
119+ {
120+ int handleInBucket = handleBucket [ i ] ;
121+ object objectInBucket = objects [ handleInBucket ] ;
122+
123+ if ( object . ReferenceEquals ( objectInBucket , obj ) )
124+ {
125+ return handleInBucket ;
126+ }
127+ }
105128 }
106129 }
107130
@@ -124,12 +147,24 @@ public static object Remove(int handle)
124147 objects [ handle ] = null ;
125148
126149 // Push the handle onto the stack
127- freeHandleStack . Push ( handle ) ;
128-
150+ handles . Push ( handle ) ;
151+
152+ uint hash = hashLookupByHandle [ handle ] ;
153+ List < int > handleBucket = null ;
154+
129155 // Remove the object from the hash dictionary's
130- var hash = hashLookupByHandle [ handle ] ;
131- handleLookupByHash . Remove ( hash ) ;
132- hashLookupByHandle . Remove ( handle ) ;
156+ if ( handleBucketByHash . TryGetValue ( hash , out handleBucket ) )
157+ {
158+ for ( int i = 0 ; i < handleBucket . Count ; i ++ )
159+ {
160+ int handleInBucket = handleBucket [ i ] ;
161+ if ( handleInBucket == handle )
162+ {
163+ handleBucket . RemoveAt ( i ) ;
164+ break ;
165+ }
166+ }
167+ }
133168
134169 return obj ;
135170 }
0 commit comments