3

I need to know, what would be proper way to implement Maps with 64 bit keys. There will not be so many items in them, I just need to use various bits of the key for various things with large enough address space and I need it to be very fast, so String keys would probably be too slow. So far I tried:

import haxe.Int64;
import haxe.Unserializer;
import haxe.Serializer;

class Test {
    static function main () {

        var key:Int64 = 1 << 63 | 0x00000001;

        var omap:Map<Int64, String> = new Map<Int64, String>();
        omap.set(key, "test");

        var smap:Map<Int64, String> = Unserializer.run(Serializer.run(omap));

        var key2:Int64 = 1 << 63 | 0x00000001;
        trace(key+" "+smap.get(key2));
    }
}

http://try.haxe.org/#7CDb2

which obviously doesn't work, because haxe.Int64 creates an object instance. Using cpp.Int64 works, because it for some reason falls back to 32 bit integer in my cpp code and I don't know what am I doing wrong. How can I force it to "stay" 64 bit, or should I do it some other way?

wildfireheart
  • 373
  • 2
  • 4
  • 13

1 Answers1

1

EDIT: This is currently not working on native targets due to bug / current implementation in hxcpp: https://github.com/HaxeFoundation/hxcpp/issues/523

I figured out this workaround / wrapper, which may not be the most efficient solution possible, but it seems to work.

import haxe.Int64;
import haxe.Unserializer;
import haxe.Serializer;

class Test {
    static function main () {

        var key:Int64 = Int64.make(1000,1);

        var omap:Int64Map<String> = new Int64Map();
        omap.set(key, "test");

        var smap:Int64Map<String> = Unserializer.run(Serializer.run(omap));

        var key2:Int64 = Int64.make(1000,1);
        trace(key+" "+smap.get(key2));
    }
}

class Int64Map<V> {

    private var map:Map<Int64,V>;

    public function new() : Void {
        this.map = new Map<Int64,V>();
    }

    public function set(key:Int64, value:V):Void {
        this.map.set(key, value);
    }

    public inline function get(key:Int64):Null<V> {
        var skey:Null<Int64> = getMapKey(key);
        if (skey != null) return this.map.get(skey);
        return null;
    }

    public inline function exists(key:Int64):Bool {
        return (getMapKey(key) != null);
    }

    public function remove( key : Int64 ) : Bool {
        var skey:Null<Int64> = getMapKey(key);
        if (skey != null) return this.map.remove(skey);
        return false;
    }

    public function keys() : Iterator<Int64> {
        return this.map.keys();
    }

    public function toString() : String {
        return this.map.toString();
    }

    public function iterator() : Iterator<V> {
        return this.map.iterator();
    }



    private function getMapKey(key:Int64):Null<Int64> {
        for (ikey in this.map.keys()){
            if (Int64.eq(key, ikey)){
                return ikey;
            }
        }
        return null;
    }

}

http://try.haxe.org/#57686

wildfireheart
  • 373
  • 2
  • 4
  • 13
  • You said there would be a small number of keys, but is the linear search ok for your use case? Wouldn't a `haxe.ds.BalancedTree` or a custom map (that has a low probability of doing the linear search) work better? – Jonas Malaco Oct 26 '16 at 14:10
  • @jonasmalacofilho It probably would, thank you for suggestion. – wildfireheart Oct 31 '16 at 12:53