|
@@ -25,9 +25,14 @@ package cs.internal;
|
|
@:final @:nativeGen
|
|
@:final @:nativeGen
|
|
@:keep @:static class FieldLookup
|
|
@:keep @:static class FieldLookup
|
|
{
|
|
{
|
|
|
|
+ @:protected private static var fieldIds:cs.NativeArray<Int>;
|
|
|
|
+ @:protected private static var fields:cs.NativeArray<String>;
|
|
|
|
+ @:protected private static var length:Int;
|
|
|
|
|
|
- @:private private static var fieldIds:Array<Int>;
|
|
|
|
- @:private private static var fields:Array<String>;
|
|
|
|
|
|
+ static function __init__()
|
|
|
|
+ {
|
|
|
|
+ length = fieldIds.Length;
|
|
|
|
+ }
|
|
|
|
|
|
//s cannot be null here
|
|
//s cannot be null here
|
|
private static inline function doHash(s:String):Int
|
|
private static inline function doHash(s:String):Int
|
|
@@ -46,7 +51,7 @@ package cs.internal;
|
|
//start of binary search algorithm
|
|
//start of binary search algorithm
|
|
var ids = fieldIds;
|
|
var ids = fieldIds;
|
|
var min = 0;
|
|
var min = 0;
|
|
- var max = ids.length;
|
|
|
|
|
|
+ var max = length;
|
|
|
|
|
|
while (min < max)
|
|
while (min < max)
|
|
{
|
|
{
|
|
@@ -72,9 +77,12 @@ package cs.internal;
|
|
var key = doHash(s);
|
|
var key = doHash(s);
|
|
|
|
|
|
//start of binary search algorithm
|
|
//start of binary search algorithm
|
|
- var ids = fieldIds;
|
|
|
|
|
|
+ var ids = fieldIds,
|
|
|
|
+ fld = fields;
|
|
var min = 0;
|
|
var min = 0;
|
|
- var max = ids.length;
|
|
|
|
|
|
+ var max = length;
|
|
|
|
+
|
|
|
|
+ var len = length;
|
|
|
|
|
|
while (min < max)
|
|
while (min < max)
|
|
{
|
|
{
|
|
@@ -86,15 +94,30 @@ package cs.internal;
|
|
} else if (key > imid) {
|
|
} else if (key > imid) {
|
|
min = mid + 1;
|
|
min = mid + 1;
|
|
} else {
|
|
} else {
|
|
- var field = fields[mid];
|
|
|
|
|
|
+ var field = fld[mid];
|
|
if (field != s)
|
|
if (field != s)
|
|
return ~key; //special case
|
|
return ~key; //special case
|
|
return key;
|
|
return key;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
//if not found, min holds the value where we should insert the key
|
|
//if not found, min holds the value where we should insert the key
|
|
- ids.insert(min, key);
|
|
|
|
- fields.insert(min, s);
|
|
|
|
|
|
+ //ensure thread safety:
|
|
|
|
+ cs.Lib.lock(FieldLookup, {
|
|
|
|
+ if (len != length) //race condition which will very rarely happen - other thread modified sooner.
|
|
|
|
+ return hash(s); //since we already own the lock, this second try will always succeed
|
|
|
|
+
|
|
|
|
+#if eraseGenerics
|
|
|
|
+ fieldIds = insertInt(fieldIds, length, min, key);
|
|
|
|
+ fields = insertString(fields, length, min, s);
|
|
|
|
+#else
|
|
|
|
+ insert(fieldIds, length, min, key);
|
|
|
|
+ insert(fields, length, min, s);
|
|
|
|
+ // ids.insert(min, key);
|
|
|
|
+ // fields.insert(min, s);
|
|
|
|
+#end
|
|
|
|
+ ++length;
|
|
|
|
+ });
|
|
return key;
|
|
return key;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -234,5 +257,6 @@ package cs.internal;
|
|
static function insertInt(a:cs.NativeArray<Int>, length:Int, pos:Int, x:Int):cs.NativeArray<Int> return __insert(a, length, pos, x);
|
|
static function insertInt(a:cs.NativeArray<Int>, length:Int, pos:Int, x:Int):cs.NativeArray<Int> return __insert(a, length, pos, x);
|
|
static function insertFloat(a:cs.NativeArray<Float>, length:Int, pos:Int, x:Float):cs.NativeArray<Float> return __insert(a, length, pos, x);
|
|
static function insertFloat(a:cs.NativeArray<Float>, length:Int, pos:Int, x:Float):cs.NativeArray<Float> return __insert(a, length, pos, x);
|
|
static function insertDynamic(a:cs.NativeArray<Dynamic>, length:Int, pos:Int, x:Dynamic):cs.NativeArray<Dynamic> return __insert(a, length, pos, x);
|
|
static function insertDynamic(a:cs.NativeArray<Dynamic>, length:Int, pos:Int, x:Dynamic):cs.NativeArray<Dynamic> return __insert(a, length, pos, x);
|
|
|
|
+ static function insertString(a:cs.NativeArray<String>, length:Int, pos:Int, x:Dynamic):cs.NativeArray<String> return __insert(a, length, pos, x);
|
|
#end
|
|
#end
|
|
}
|
|
}
|