package ch.ethz.globis.distindex.client.pht;

import ch.ethz.globis.distindex.client.util.UnsafeUtil;
import ch.ethz.globis.pht.*;
import sun.misc.Unsafe;

import java.lang.reflect.Field;

public class PHFactory {

    private String zkHost;
    private int zkPort;

    public PHFactory(String zkHost, int zkPort) {
        this.zkHost = zkHost;
        this.zkPort = zkPort;
    }

    public <V> PhTreeV<V> createPHTreeMap(int dim, int depth, Class<V> valueClass) {
        DistributedPHTreeProxy<V> proxy = new DistributedPHTreeProxy<>(zkHost, zkPort, valueClass);
        proxy.create(dim, depth);
        return new DistributedPhTreeV<>(proxy);
    }

    public <V> PhTreeVD<V> createPHTreeVD(int dim, Class<V> valueClass) {
        PhTreeV<V> proxy = createPHTreeMap(dim, Double.SIZE, valueClass);

        PhTreeVD<V> tree = new PhTreeVD<>(dim);
        Unsafe unsafe = UnsafeUtil.get();
        try {
            Field field = PhTreeVD.class.getDeclaredField("pht");
            long offset = unsafe.objectFieldOffset(field);
            unsafe.putObject(tree, offset, proxy);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }

        return tree;
    }

    public PhTree createPHTreeSet(int dim, int depth) {
        PhTreeV<Object> backingTree = createPHTreeMap(dim, depth, Object.class);

        PhTree tree = PhTree.create(dim, depth);
        Unsafe unsafe = UnsafeUtil.get();
        try {
            Field field = PhTreeVProxy.class.getDeclaredField("tree");
            long offset = unsafe.objectFieldOffset(field);
            unsafe.putObject(tree, offset, backingTree);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        return tree;
    }

    public PhTreeRangeD createPHTreeRangeSet(int dim, int depth) {
        PhTree backingTree = createPHTreeSet(2 * dim, depth);

        PhTreeRangeD tree = new PhTreeRangeD(dim);
        Unsafe unsafe = UnsafeUtil.get();
        try {
            Field field = PhTreeRangeD.class.getDeclaredField("pht");
            long offset = unsafe.objectFieldOffset(field);
            unsafe.putObject(tree, offset, backingTree);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        return tree;
    }
}
@@ -65,126 +65,13 @@
 bis.
-distindex.client.util.UnsafeUtil;%0Aimport ch.ethz.globis.pht.*;%0Aimport sun.misc.Unsafe;%0A%0Aimport java.lang.reflect.Field
+pht.*
 ;%0A%0Ap
@@ -699,386 +699,36 @@
     
-PhTreeVD%3CV%3E tree = new PhTreeVD%3C%3E(dim);%0A        Unsafe unsafe = UnsafeUtil.get();%0A        try %7B%0A            Field field = PhTreeVD.class.getDeclaredField(%22pht%22);%0A            long offset = unsafe.objectFieldOffset(field);%0A            unsafe.putObject(tree, offset, proxy);%0A        %7D catch (NoSuchFieldException e) %7B%0A            e.printStackTrace();%0A        %7D%0A%0A        return tree
+return new PhTreeVD%3C%3E(proxy)
 ;%0A  
@@ -812,27 +812,21 @@
 Object%3E 
-backingTree
+proxy
  = creat
@@ -876,934 +876,221 @@
     
-PhTree tree = PhTree.create(dim, depth);%0A        Unsafe unsafe = UnsafeUtil.get();%0A        try %7B%0A            Field field = PhTreeVProxy.class.getDeclaredField(%22tree%22);%0A            long offset = unsafe.objectFieldOffset(field);%0A            unsafe.putObject(tree, offset, backingTree);%0A        %7D catch (NoSuchFieldException e) %7B%0A            e.printStackTrace();%0A        %7D%0A        return tree;%0A    %7D%0A%0A    public PhTreeRangeD createPHTreeRangeSet(int dim, int depth) %7B%0A        PhTree backingTree = createPHTreeSet(2 * dim, depth);%0A%0A        PhTreeRangeD tree = new PhTreeRangeD(dim);%0A        Unsafe unsafe = UnsafeUtil.get();%0A        try %7B%0A            Field field = PhTreeRangeD.class.getDeclaredField(%22pht%22);%0A            long offset = unsafe.objectFieldOffset(field);%0A            unsafe.putObject(tree, offset, backingTree);%0A        %7D catch (NoSuchFieldException e) %7B%0A            e.printStackTrace();%0A        %7D%0A        return tree
+return new PhTreeVProxy(proxy);%0A    %7D%0A%0A    public PhTreeRangeD createPHTreeRangeSet(int dim, int depth) %7B%0A        PhTree backingTree = createPHTreeSet(2 * dim, depth);%0A%0A        return new PhTreeRangeD(backingTree)
 ;%0A  

Index distribution Updated PHFactory to use the proper constructors.