@@ -945,96 +945,6 @@ public ref TEntry AddKeyAndGetEntryRef(K key, int index)
945945 }
946946 }
947947
948- // todo: @perf optimize with SIMD, ILP, loop-unrolling, etc.
949- /// <summary>Lookup for the K in the TStackEntries, first by calculating it hash with TEq and searching the hash in the TStackHashes</summary>
950- public static ref TEntry TryGetEntryRef_loop < K , TEntry , TEq , TStackHashes , TStackEntries > (
951- this ref TStackEntries entries , ref TStackHashes hashes , K key , out bool found ,
952- TEq eq = default , Use < TEntry > _ = default )
953- where TEntry : struct , IEntry < K >
954- where TEq : struct , IEq < K >
955- where TStackHashes : struct , IStack < int , TStackHashes >
956- where TStackEntries : struct , IStack < TEntry , TStackEntries >
957- {
958- Debug . Assert ( hashes . Capacity == entries . Capacity ,
959- "Expecting that the hashes and entries stacks have the same capacity" ) ;
960-
961- var hash = eq . GetHashCode ( key ) ;
962-
963- for ( var i = 0 ; i < hashes . Capacity ; ++ i )
964- {
965- var h = hashes . GetSurePresentItemRef ( i ) ;
966- if ( h == hash )
967- {
968- ref var entry = ref entries . GetSurePresentItemRef ( i ) ;
969- if ( found = eq . Equals ( entry . Key , key ) )
970- return ref entry ;
971- }
972- }
973-
974- found = false ;
975- return ref RefTools < TEntry > . GetNullRef ( ) ;
976- }
977-
978- /// <summary>Lookup for the K in the TStackEntries, first by calculating it hash with TEq and searching the hash in the TStackHashes</summary>
979- public static ref TEntry TryGetEntryRef_ILP < K , TEntry , TEq , TStackHashes , TStackEntries , TCap > (
980- this ref TStackEntries entries , ref TStackHashes hashes , K key , out bool found ,
981- TEq eq = default , TCap cap = default , Use < TEntry > _ = default )
982- where TEntry : struct , IEntry < K >
983- where TEq : struct , IEq < K >
984- where TStackHashes : struct , IStack < int , TCap , TStackHashes >
985- where TStackEntries : struct , IStack < TEntry , TCap , TStackEntries >
986- where TCap : struct , ISize4Plus
987- {
988- var hash = eq . GetHashCode ( key ) ;
989-
990- for ( var i = 0 ; i < cap . Size ; i += 4 )
991- {
992- ref var h0 = ref hashes . GetSurePresentItemRef ( i ) ;
993- ref var h1 = ref hashes . GetSurePresentItemRef ( i + 1 ) ;
994- ref var h2 = ref hashes . GetSurePresentItemRef ( i + 2 ) ;
995- ref var h3 = ref hashes . GetSurePresentItemRef ( i + 3 ) ;
996-
997- var match0 = h0 == hash ;
998- var match1 = h1 == hash ;
999- var match2 = h2 == hash ;
1000- var match3 = h3 == hash ;
1001-
1002- if ( ! ( match0 | match1 | match2 | match3 ) )
1003- continue ;
1004-
1005- if ( match0 )
1006- {
1007- ref var entry0 = ref entries . GetSurePresentItemRef ( i ) ;
1008- if ( found = eq . Equals ( entry0 . Key , key ) )
1009- return ref entry0 ;
1010- }
1011-
1012- if ( match1 )
1013- {
1014- ref var entry1 = ref entries . GetSurePresentItemRef ( i + 1 ) ;
1015- if ( found = eq . Equals ( entry1 . Key , key ) )
1016- return ref entry1 ;
1017- }
1018-
1019- if ( match2 )
1020- {
1021- ref var entry2 = ref entries . GetSurePresentItemRef ( i + 2 ) ;
1022- if ( found = eq . Equals ( entry2 . Key , key ) )
1023- return ref entry2 ;
1024- }
1025-
1026- if ( match3 )
1027- {
1028- ref var entry3 = ref entries . GetSurePresentItemRef ( i + 3 ) ;
1029- if ( found = eq . Equals ( entry3 . Key , key ) )
1030- return ref entry3 ;
1031- }
1032- }
1033-
1034- found = false ;
1035- return ref RefTools < TEntry > . GetNullRef ( ) ;
1036- }
1037-
1038948 /// <summary>Lookup for the K in the TStackEntries, first by calculating it hash with TEq and searching the hash in the TStackHashes</summary>
1039949 public static ref TEntry TryGetEntryRef < K , TEntry , TEq , TCap , TStackHashes , TStackEntries > (
1040950 this ref TStackEntries entries , ref TStackHashes hashes , K key , out bool found ,
@@ -1078,67 +988,14 @@ public static ref TEntry TryGetEntryRef<K, TEntry, TEq, TCap, TStackHashes, TSta
1078988 }
1079989#endif
1080990
1081- if ( cap . Size >= 4 )
1082- {
1083- for ( var i = 0 ; i < hashes . Capacity ; i += 4 )
1084- {
1085- ref var h0 = ref hashes . GetSurePresentItemRef ( i ) ;
1086- ref var h1 = ref hashes . GetSurePresentItemRef ( i + 1 ) ;
1087- ref var h2 = ref hashes . GetSurePresentItemRef ( i + 2 ) ;
1088- ref var h3 = ref hashes . GetSurePresentItemRef ( i + 3 ) ;
1089-
1090- var match0 = h0 == hash ;
1091- var match1 = h1 == hash ;
1092- var match2 = h2 == hash ;
1093- var match3 = h3 == hash ;
1094-
1095- if ( ! ( match0 | match1 | match2 | match3 ) )
1096- continue ;
1097-
1098- if ( match0 )
1099- {
1100- ref var entry0 = ref entries . GetSurePresentItemRef ( i ) ;
1101- if ( found = eq . Equals ( entry0 . Key , key ) )
1102- return ref entry0 ;
1103- }
1104-
1105- if ( match1 )
1106- {
1107- ref var entry1 = ref entries . GetSurePresentItemRef ( i + 1 ) ;
1108- if ( found = eq . Equals ( entry1 . Key , key ) )
1109- return ref entry1 ;
1110- }
1111-
1112- if ( match2 )
1113- {
1114- ref var entry2 = ref entries . GetSurePresentItemRef ( i + 2 ) ;
1115- if ( found = eq . Equals ( entry2 . Key , key ) )
1116- return ref entry2 ;
1117- }
1118-
1119- if ( match3 )
1120- {
1121- ref var entry3 = ref entries . GetSurePresentItemRef ( i + 3 ) ;
1122- if ( found = eq . Equals ( entry3 . Key , key ) )
1123- return ref entry3 ;
1124- }
1125- }
1126- }
1127- else
991+ for ( var i = 0 ; i < hashes . Capacity ; ++ i )
1128992 {
1129- ref var h0 = ref hashes . GetSurePresentItemRef ( 0 ) ;
1130- ref var h1 = ref hashes . GetSurePresentItemRef ( 1 ) ;
1131- if ( h0 == hash )
1132- {
1133- ref var entry0 = ref entries . GetSurePresentItemRef ( 0 ) ;
1134- if ( found = eq . Equals ( entry0 . Key , key ) )
1135- return ref entry0 ;
1136- }
1137- if ( h1 == hash )
993+ var h = hashes . GetSurePresentItemRef ( i ) ;
994+ if ( h == hash )
1138995 {
1139- ref var entry1 = ref entries . GetSurePresentItemRef ( 1 ) ;
1140- if ( found = eq . Equals ( entry1 . Key , key ) )
1141- return ref entry1 ;
996+ ref var entry = ref entries . GetSurePresentItemRef ( i ) ;
997+ if ( found = eq . Equals ( entry . Key , key ) )
998+ return ref entry ;
1142999 }
11431000 }
11441001
@@ -1150,30 +1007,36 @@ public static ref TEntry TryGetEntryRef<K, TEntry, TEq, TCap, TStackHashes, TSta
11501007 /// or adds a new entry (found == false) and returns it.Value by ref.
11511008 /// So the method always return a non-null ref to the value, either existing or added</summary>
11521009 [ MethodImpl ( ( MethodImplOptions ) 256 ) ]
1153- public static ref V AddOrGetValueRef < K , V , TEq , TStackEntries , TEntries > (
1154- this ref SmallMap < K , Entry < K , V > , TEq , TStackEntries , TEntries > map , K key , out bool found )
1010+ public static ref V AddOrGetValueRef < K , V , TEq , TStackCap , TStackHashes , TStackEntries , TEntries > (
1011+ this ref SmallMap < K , Entry < K , V > , TEq , TStackCap , TStackHashes , TStackEntries , TEntries > map , K key , out bool found )
11551012 where TEq : struct , IEq < K >
1156- where TStackEntries : struct , IStack < Entry < K , V > , TStackEntries >
1013+ where TStackCap : struct , ISize2Plus
1014+ where TStackHashes : struct , IStack < int , TStackCap , TStackHashes >
1015+ where TStackEntries : struct , IStack < Entry < K , V > , TStackCap , TStackEntries >
11571016 where TEntries : struct , IEntries < K , Entry < K , V > , TEq > =>
11581017 ref map . AddOrGetEntryRef ( key , out found ) . Value ;
11591018
11601019 /// <summary>Adds an entry for sure absent key.
11611020 /// Provides the performance in scenarios where you look for the present key, and using it, and if ABSENT then add the new one.
11621021 /// So this method optimized NOT to look for the present item for the second time</summary>
11631022 [ MethodImpl ( ( MethodImplOptions ) 256 ) ]
1164- public static ref V AddSureAbsentDefaultAndGetRef < K , V , TEq , TStackEntries , TEntries > (
1165- this ref SmallMap < K , Entry < K , V > , TEq , TStackEntries , TEntries > map , K key )
1023+ public static ref V AddSureAbsentDefaultAndGetRef < K , V , TEq , TStackCap , TStackHashes , TStackEntries , TEntries > (
1024+ this ref SmallMap < K , Entry < K , V > , TEq , TStackCap , TStackHashes , TStackEntries , TEntries > map , K key )
11661025 where TEq : struct , IEq < K >
1167- where TStackEntries : struct , IStack < Entry < K , V > , TStackEntries >
1026+ where TStackCap : struct , ISize2Plus
1027+ where TStackHashes : struct , IStack < int , TStackCap , TStackHashes >
1028+ where TStackEntries : struct , IStack < Entry < K , V > , TStackCap , TStackEntries >
11681029 where TEntries : struct , IEntries < K , Entry < K , V > , TEq >
11691030 => ref map . AddSureAbsentDefaultEntryAndGetRef ( key ) . Value ;
11701031
11711032 /// <summary>Lookups for the stored entry by key. Returns the ref to the found entry.Value or the null ref</summary>
11721033 [ MethodImpl ( ( MethodImplOptions ) 256 ) ]
1173- public static ref V TryGetValueRef < K , V , TEq , TStackEntries , TEntries > (
1174- this ref SmallMap < K , Entry < K , V > , TEq , TStackEntries , TEntries > map , K key , out bool found )
1034+ public static ref V TryGetValueRef < K , V , TEq , TStackCap , TStackHashes , TStackEntries , TEntries > (
1035+ this ref SmallMap < K , Entry < K , V > , TEq , TStackCap , TStackHashes , TStackEntries , TEntries > map , K key , out bool found )
11751036 where TEq : struct , IEq < K >
1176- where TStackEntries : struct , IStack < Entry < K , V > , TStackEntries >
1037+ where TStackCap : struct , ISize2Plus
1038+ where TStackHashes : struct , IStack < int , TStackCap , TStackHashes >
1039+ where TStackEntries : struct , IStack < Entry < K , V > , TStackCap , TStackEntries >
11771040 where TEntries : struct , IEntries < K , Entry < K , V > , TEq >
11781041 {
11791042 ref var e = ref map . TryGetEntryRef ( key , out found ) ;
@@ -1198,10 +1061,12 @@ public static ref V TryGetValueRef<K, V, TEq, TStackEntries, TEntries>(
11981061///
11991062/// </summary>
12001063[ DebuggerDisplay ( "{Count} of {_e0}, {_e1}, {_e2}, {_e3}, ..." ) ]
1201- public struct SmallMap < K , TEntry , TEq , TStackEntries , TEntries >
1064+ public struct SmallMap < K , TEntry , TEq , TStackCap , TStackHashes , TStackEntries , TEntries >
12021065 where TEntry : struct , IEntry < K >
12031066 where TEq : struct , IEq < K >
1204- where TStackEntries : struct , IStack < TEntry , TStackEntries >
1067+ where TStackCap : struct , ISize2Plus
1068+ where TStackHashes : struct , IStack < int , TStackCap , TStackHashes >
1069+ where TStackEntries : struct , IStack < TEntry , TStackCap , TStackEntries >
12051070 where TEntries : struct , IEntries < K , TEntry , TEq >
12061071{
12071072 internal byte _capacityBitShift ;
@@ -1219,6 +1084,7 @@ public struct SmallMap<K, TEntry, TEq, TStackEntries, TEntries>
12191084 internal TEntries _entries ;
12201085#pragma warning restore IDE0044
12211086#pragma warning disable CS0649 // Field 'SmallMap<K, V, TEq, TStack, TEntries>.Stack' is never assigned to, and will always have its default value
1087+ internal TStackHashes StackHashes ;
12221088 internal TStackEntries StackEntries ;
12231089#pragma warning restore CS0649
12241090
@@ -1614,42 +1480,42 @@ internal int ResizeHashes(int indexMask)
16141480public struct SmallMap4 < K , V , TEq > ( ) where TEq : struct , IEq < K >
16151481{
16161482 /// <summary>Map with 4 elements on stack and entries baked by the single array</summary>
1617- public SmallMap < K , SmallMap . Entry < K , V > , TEq , Stack4 < SmallMap . Entry < K , V > > , SmallMap . SingleArrayEntries < K , SmallMap . Entry < K , V > , TEq > > Map ;
1483+ public SmallMap < K , SmallMap . Entry < K , V > , TEq , Size4 , Stack4 < int > , Stack4 < SmallMap . Entry < K , V > > , SmallMap . SingleArrayEntries < K , SmallMap . Entry < K , V > , TEq > > Map ;
16181484}
16191485
16201486/// <summary>Holds the Map with 8 items on stack. Minimizes the number of type arguments required to be specified</summary>
16211487public struct SmallMap8 < K , V , TEq > ( ) where TEq : struct , IEq < K >
16221488{
16231489 /// <summary>Map with 8 elements on stack and entries baked by the single array</summary>
1624- public SmallMap < K , SmallMap . Entry < K , V > , TEq , Stack8 < SmallMap . Entry < K , V > > , SmallMap . SingleArrayEntries < K , SmallMap . Entry < K , V > , TEq > > Map ;
1490+ public SmallMap < K , SmallMap . Entry < K , V > , TEq , Size8 , Stack8 < int > , Stack8 < SmallMap . Entry < K , V > > , SmallMap . SingleArrayEntries < K , SmallMap . Entry < K , V > , TEq > > Map ;
16251491}
16261492
16271493/// <summary>Holds the Map with 16 items on stack. Minimizes the number of type arguments required to be specified</summary>
16281494public struct SmallMap16 < K , V , TEq > ( ) where TEq : struct , IEq < K >
16291495{
16301496 /// <summary>Map with 16 elements on stack and entries baked by the single array</summary>
1631- public SmallMap < K , SmallMap . Entry < K , V > , TEq , Stack16 < SmallMap . Entry < K , V > > , SmallMap . SingleArrayEntries < K , SmallMap . Entry < K , V > , TEq > > Map ;
1497+ public SmallMap < K , SmallMap . Entry < K , V > , TEq , Size16 , Stack16 < int > , Stack16 < SmallMap . Entry < K , V > > , SmallMap . SingleArrayEntries < K , SmallMap . Entry < K , V > , TEq > > Map ;
16321498}
16331499
16341500/// <summary>Holds the Set with 4 items on stack. Minimizes the number of type arguments required to be specified</summary>
16351501public struct SmallSet4 < K , TEq > ( ) where TEq : struct , IEq < K >
16361502{
16371503 /// <summary>Set with 4 keys on stack and entries baked by the single array</summary>
1638- public SmallMap < K , SmallMap . Entry < K > , TEq , Stack4 < SmallMap . Entry < K > > , SmallMap . SingleArrayEntries < K , SmallMap . Entry < K > , TEq > > Set ;
1504+ public SmallMap < K , SmallMap . Entry < K > , TEq , Size4 , Stack4 < int > , Stack4 < SmallMap . Entry < K > > , SmallMap . SingleArrayEntries < K , SmallMap . Entry < K > , TEq > > Set ;
16391505}
16401506
16411507/// <summary>Holds the Set with 8 items on stack. Minimizes the number of type arguments required to be specified</summary>
16421508public struct SmallSet8 < K , TEq > ( ) where TEq : struct , IEq < K >
16431509{
16441510 /// <summary>Set with 8 keys on stack and entries baked by the single array</summary>
1645- public SmallMap < K , SmallMap . Entry < K > , TEq , Stack8 < SmallMap . Entry < K > > , SmallMap . SingleArrayEntries < K , SmallMap . Entry < K > , TEq > > Set ;
1511+ public SmallMap < K , SmallMap . Entry < K > , TEq , Size8 , Stack8 < int > , Stack8 < SmallMap . Entry < K > > , SmallMap . SingleArrayEntries < K , SmallMap . Entry < K > , TEq > > Set ;
16461512}
16471513
16481514/// <summary>Holds the Set with 16 items on stack. Minimizes the number of type arguments required to be specified</summary>
16491515public struct SmallSet16 < K , TEq > ( ) where TEq : struct , IEq < K >
16501516{
16511517 /// <summary>Set with 16 keys on stack and entries baked by the single array</summary>
1652- public SmallMap < K , SmallMap . Entry < K > , TEq , Stack16 < SmallMap . Entry < K > > , SmallMap . SingleArrayEntries < K , SmallMap . Entry < K > , TEq > > Set ;
1518+ public SmallMap < K , SmallMap . Entry < K > , TEq , Size16 , Stack16 < int > , Stack16 < SmallMap . Entry < K > > , SmallMap . SingleArrayEntries < K , SmallMap . Entry < K > , TEq > > Set ;
16531519}
16541520
16551521#nullable restore
0 commit comments