94 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
			
		
		
	
	
			94 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
| import haxe.ds.WeakMap;
 | |
| 
 | |
| class WeakObjectData
 | |
| {
 | |
|    public var id:Int;
 | |
|    public function new(inId:Int) id = inId;
 | |
|    public function toString() return "Data " + id;
 | |
| }
 | |
| 
 | |
| 
 | |
| class TestWeakHash extends haxe.unit.TestCase
 | |
| {
 | |
|    var retained:Array<WeakObjectData>;
 | |
| 
 | |
|    function createMap(inCount:Int)
 | |
|    {
 | |
|       retained = [];
 | |
|       var map = new WeakMap<WeakObjectData,Int>();
 | |
|       for(i in 0...inCount)
 | |
|       {
 | |
|          var obj = new WeakObjectData(i);
 | |
|          if ( (i&1)==0 )
 | |
|             retained.push(obj);
 | |
|          map.set(obj,i);
 | |
|       }
 | |
|       return map;
 | |
|    }
 | |
|    function createMapDeep(inDepth:Int, inCount:Int)
 | |
|    {
 | |
|       if (inDepth<1)
 | |
|          return createMap(inCount);
 | |
| 
 | |
|       return createMapDeep(inDepth-1, inCount);
 | |
|    }
 | |
| 
 | |
|    function checkMap(map:WeakMap<WeakObjectData,Int>, expect:Int)
 | |
|    {
 | |
|       var valid = 0;
 | |
|       var oddFound = 0;
 | |
|       for(k in map.keys())
 | |
|       {
 | |
|          if( (k.id&1)!= 0)
 | |
|          {
 | |
|             oddFound ++;
 | |
|             //throw "Odd retained " + k.id;
 | |
|          }
 | |
|          else
 | |
|             valid++;
 | |
|       }
 | |
|       // There may be one or two values lurking on the stack, which is conservatively marked
 | |
|       if (oddFound>2)
 | |
|          trace("Too many odd values retained " + oddFound);
 | |
|       if (!(valid>=expect && valid<expect+2))
 | |
|          trace("WeakHash invalid range "+ expect + "..." + valid + "..." + (expect+2) );
 | |
|       assertTrue(valid>=expect && valid<expect+2);
 | |
|    }
 | |
|    function deepCheckMap(inDepth:Int, map:WeakMap<WeakObjectData,Int>, expect:Int)
 | |
|    {
 | |
|       if (inDepth<1)
 | |
|          checkMap(map,expect);
 | |
|       else
 | |
|          deepCheckMap(inDepth-1, map, expect);
 | |
|    }
 | |
| 
 | |
|    function deepClearRetained(inRecurse:Int)
 | |
|    {
 | |
|       if (inRecurse>0)
 | |
|          deepClearRetained(inRecurse-1);
 | |
|       else
 | |
|          retained = [];
 | |
|    }
 | |
| 
 | |
|    public function test()
 | |
|    {
 | |
|       var err = "";
 | |
|       try
 | |
|       {
 | |
|          var map = createMapDeep(20,1000);
 | |
|          cpp.vm.Gc.run(true);
 | |
|          deepCheckMap(10,map,500);
 | |
|          deepClearRetained(10);
 | |
|          cpp.vm.Gc.run(true);
 | |
|          checkMap(map,0);
 | |
|       }
 | |
|       catch(e:String)
 | |
|       {
 | |
|          trace(e);
 | |
|          err = e;
 | |
|       }
 | |
|       assertTrue(err=="");
 | |
|    }
 | |
| 
 | |
| }
 |