Added a function to the registry to allocate a block of numbers unique within the whole cluster using Curator's DistributedAtomicLong
diff --git a/src/main/java/net/onrc/onos/registry/controller/IControllerRegistryService.java b/src/main/java/net/onrc/onos/registry/controller/IControllerRegistryService.java
index dadee65..21da47e 100644
--- a/src/main/java/net/onrc/onos/registry/controller/IControllerRegistryService.java
+++ b/src/main/java/net/onrc/onos/registry/controller/IControllerRegistryService.java
@@ -115,4 +115,7 @@
 	 * @return Collection of dpids
 	 */
 	public Collection<Long> getSwitchesControlledByController(String controllerId);
+	
+	public IdBlock allocateUniqueIdBlock();
+	
 }
diff --git a/src/main/java/net/onrc/onos/registry/controller/IdBlock.java b/src/main/java/net/onrc/onos/registry/controller/IdBlock.java
new file mode 100644
index 0000000..64b2af8
--- /dev/null
+++ b/src/main/java/net/onrc/onos/registry/controller/IdBlock.java
@@ -0,0 +1,31 @@
+package net.onrc.onos.registry.controller;
+
+public class IdBlock {
+	private long start;
+	private long end;
+	private long size;
+	
+	public IdBlock(long start, long end, long size) {
+		this.start = start;
+		this.end = end;
+		this.size = size;
+	}
+	
+	public long getStart() {
+		return start;
+	}
+
+	public long getEnd() {
+		return end;
+	}
+
+	public long getSize() {
+		return size;
+	}
+	
+	@Override
+	public String toString() {
+		return "IdBlock [start=" + start + ", end=" + end + ", size=" + size
+				+ "]";
+	}
+}
diff --git a/src/main/java/net/onrc/onos/registry/controller/StandaloneRegistry.java b/src/main/java/net/onrc/onos/registry/controller/StandaloneRegistry.java
index 2c220fd..e48c519 100644
--- a/src/main/java/net/onrc/onos/registry/controller/StandaloneRegistry.java
+++ b/src/main/java/net/onrc/onos/registry/controller/StandaloneRegistry.java
@@ -115,6 +115,12 @@
 			String controllerId) {
 		throw new RuntimeException("Not yet implemented");
 	}
+	
+	@Override
+	public IdBlock allocateUniqueIdBlock(){
+		//XXX Not exactly unique...
+		return new IdBlock(0L, 0x10000000L, 0x10000000L);
+	}
 
 	@Override
 	public Collection<Class<? extends IFloodlightService>> getModuleServices() {
diff --git a/src/main/java/net/onrc/onos/registry/controller/ZookeeperRegistry.java b/src/main/java/net/onrc/onos/registry/controller/ZookeeperRegistry.java
index 76b7ebd..82259a9 100644
--- a/src/main/java/net/onrc/onos/registry/controller/ZookeeperRegistry.java
+++ b/src/main/java/net/onrc/onos/registry/controller/ZookeeperRegistry.java
@@ -24,6 +24,8 @@
 import com.netflix.curator.RetryPolicy;
 import com.netflix.curator.framework.CuratorFramework;
 import com.netflix.curator.framework.CuratorFrameworkFactory;
+import com.netflix.curator.framework.recipes.atomic.AtomicValue;
+import com.netflix.curator.framework.recipes.atomic.DistributedAtomicLong;
 import com.netflix.curator.framework.recipes.cache.ChildData;
 import com.netflix.curator.framework.recipes.cache.PathChildrenCache;
 import com.netflix.curator.framework.recipes.cache.PathChildrenCache.StartMode;
@@ -33,6 +35,7 @@
 import com.netflix.curator.framework.recipes.leader.LeaderLatchEvent;
 import com.netflix.curator.framework.recipes.leader.LeaderLatchListener;
 import com.netflix.curator.retry.ExponentialBackoffRetry;
+import com.netflix.curator.retry.RetryOneTime;
 import com.netflix.curator.x.discovery.ServiceCache;
 import com.netflix.curator.x.discovery.ServiceDiscovery;
 import com.netflix.curator.x.discovery.ServiceDiscoveryBuilder;
@@ -67,6 +70,10 @@
 	protected ConcurrentHashMap<String, SwitchLeadershipData> switches;
 	protected Map<String, PathChildrenCache> switchPathCaches;
 	
+	private final String ID_COUNTER_PATH = "/flowidcounter";
+	private final Long ID_BLOCK_SIZE = 0x100000000L;
+	protected DistributedAtomicLong distributedIdCounter;
+	
 	//Zookeeper performance-related configuration
 	protected static final int sessionTimeout = 5000;
 	protected static final int connectionTimeout = 7000;
@@ -372,6 +379,21 @@
 		return data;
 	}
 	
+	public IdBlock allocateUniqueIdBlock(){
+		try {
+			AtomicValue<Long> result = null;
+			do {
+				result = distributedIdCounter.add(ID_BLOCK_SIZE);
+			} while (result == null || !result.succeeded());
+			
+			return new IdBlock(result.preValue(), result.postValue() - 1, ID_BLOCK_SIZE);
+		} catch (Exception e) {
+			log.error("Error allocating ID block");
+		} 
+		
+		return null;
+	}
+	
 	/*
 	 * IFloodlightModule
 	 */
@@ -427,6 +449,10 @@
 		client.start();
 		client = client.usingNamespace(namespace);
 
+		distributedIdCounter = new DistributedAtomicLong(
+				client, 
+				ID_COUNTER_PATH, 
+				new RetryOneTime(100));
 		
 		switchCache = new PathChildrenCache(client, switchLatchesPath, true);
 		switchCache.getListenable().addListener(switchPathCacheListener);