9
9
*/
10
10
package org .truffleruby .core .hash ;
11
11
12
+ import com .oracle .truffle .api .CompilerDirectives .TruffleBoundary ;
12
13
import org .truffleruby .RubyContext ;
13
14
import org .truffleruby .RubyLanguage ;
14
15
import org .truffleruby .core .hash .library .EmptyHashStore ;
16
+ import org .truffleruby .core .hash .library .HashStoreLibrary ;
15
17
import org .truffleruby .core .numeric .BigIntegerOps ;
16
18
import org .truffleruby .core .numeric .RubyBignum ;
17
19
import org .truffleruby .language .RubyBaseNode ;
18
20
21
+ import java .util .Map ;
22
+ import java .util .Optional ;
23
+ import java .util .function .Function ;
24
+
19
25
public abstract class HashOperations {
20
26
21
27
public static RubyHash newEmptyHash (RubyContext context , RubyLanguage language ) {
@@ -27,6 +33,22 @@ public static RubyHash newEmptyHash(RubyContext context, RubyLanguage language)
27
33
0 );
28
34
}
29
35
36
+ @ TruffleBoundary
37
+ public static <K , V > RubyHash toRubyHash (RubyContext context , RubyLanguage language ,
38
+ HashStoreLibrary hashStoreLibrary , Map <K , V > map , Optional <Function <K , Object >> keyMapper ,
39
+ Optional <Function <V , Object >> valueMapper , boolean byIdentity ) {
40
+ final RubyHash ret = newEmptyHash (context , language );
41
+
42
+ for (Map .Entry <K , V > entry : map .entrySet ()) {
43
+ final Object key = keyMapper .isPresent () ? keyMapper .get ().apply (entry .getKey ()) : entry .getKey ();
44
+ final Object value = valueMapper .isPresent () ? valueMapper .get ().apply (entry .getValue ()) : entry .getValue ();
45
+
46
+ hashStoreLibrary .set (ret .store , ret , key , value , byIdentity );
47
+ }
48
+
49
+ return ret ;
50
+ }
51
+
30
52
// random number, stops hashes for similar values but different classes being the same, static because we want deterministic hashes
31
53
public static final int BOOLEAN_CLASS_SALT = 55927484 ;
32
54
public static final int INTEGER_CLASS_SALT = 1028093337 ;
0 commit comments