/*
 * Copyright (c) 2012 Mateusz Parzonka, Eric Bodden
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 * Mateusz Parzonka - initial API and implementation
 */
package prm4j.indexing.realtime;

import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

import prm4j.indexing.map.MinimalMapEntry;

public class DefaultLowLevelBinding extends WeakReference<Object> implements LowLevelBinding,
	MinimalMapEntry<Object, DefaultLowLevelBinding> {

    private long timestamp;
    private boolean disabled;
    private final int hashCode;
    @Deprecated
    private DefaultLowLevelBinding next;
    private List<WeakReference<Node>> nodeRefs;

    public DefaultLowLevelBinding(Object boundObject, int hashCode, ReferenceQueue<Object> q) {
	super(boundObject, q);
	this.hashCode = hashCode;
	timestamp = Long.MAX_VALUE; // indicates the binding was just created
	nodeRefs = new ArrayList<WeakReference<Node>>();
    }

    /**
     * {@inheritDoc}
     *
     * The key used in the {@link BindingStore} is the object.
     */
    @Override
    public Object getKey() {
	return get();
    }

    @Override
    public int hashCode() {
        return hashCode;
    }

    @Override
    public DefaultLowLevelBinding next() {
	return next;
    }

    @Override
    public void setNext(DefaultLowLevelBinding next) {
	this.next = next;
    }

    @Override
    public void registerNode(WeakReference<Node> nodeReference) {
	nodeRefs.add(nodeReference);
    }

    @Override
    public void release() {
	for (WeakReference<Node> ref : nodeRefs) {
	    final Node node = ref.get();
	    if (node != null) {
		node.remove(this);
	    }
	}
	nodeRefs = null;
    }

    @Override
    public boolean isDisabled() {
	return disabled;
    }

    @Override
    public void setDisabled(boolean disabled) {
	this.disabled = disabled;

    }

    @Override
    public long getTimestamp() {
	return timestamp;
    }

    @Override
    public void setTimestamp(long timestamp) {
	this.timestamp = timestamp;
    }

    @Override
    public String toString() {
	return "Binding(" + hashCode + ")=" + get();
    }

}

@@ -504,79 +504,9 @@
 rray
-List;%0Aimport java.util.List;%0A%0Aimport prm4j.indexing.map.MinimalMapEntry
+s
 ;%0A%0Ap
@@ -600,58 +600,8 @@
 ding
-,%0A%09MinimalMapEntry%3CObject, DefaultLowLevelBinding%3E
  %7B%0A%0A
@@ -694,24 +694,8 @@
 de;%0A
-    @Deprecated%0A
     
@@ -702,23 +702,16 @@
 private 
-Default
 LowLevel
@@ -740,33 +740,42 @@
 ate 
-List%3CWeakReference%3CNode%3E%3E
+Object%5B%5D nodeRefs;%0A    private int
  nod
@@ -779,16 +779,20 @@
 nodeRefs
+Size
 ;%0A%0A    p
@@ -878,16 +878,41 @@
 bject%3E q
+, int initialNodeRefsSize
 ) %7B%0A%09sup
@@ -1049,40 +1049,35 @@
 new 
-ArrayList%3CWeakReference%3CNode%3E%3E()
+Object%5BinitialNodeRefsSize%5D
 ;%0A  
@@ -1299,16 +1299,9 @@
 ) %7B%0A
-        
+%09
 retu
@@ -1337,39 +1337,32 @@
 ride%0A    public 
-Default
 LowLevelBinding 
@@ -1429,23 +1429,16 @@
 setNext(
-Default
 LowLevel
@@ -1564,21 +1564,206 @@
  %7B%0A%09
-nodeRefs.add(
+// ensure capacity%0A%09if (nodeRefsSize %3E= nodeRefs.length) %7B%0A%09    final int capacity = (nodeRefs.length * 3) / 2 + 1;%0A%09    nodeRefs = Arrays.copyOf(nodeRefs, capacity);%0A%09%7D%0A%09nodeRefs%5BnodeRefsSize++%5D = 
 node
@@ -1771,17 +1771,16 @@
 eference
-)
 ;%0A    %7D%0A
@@ -1832,72 +1832,138 @@
 or (
-WeakReference%3CNode%3E ref : nodeRefs) %7B%0A%09    final Node node = ref
+int i = 0; i %3C nodeRefsSize; i++) %7B%0A%09    @SuppressWarnings(%22unchecked%22)%0A%09    final Node node = ((WeakReference%3CNode%3E) nodeRefs%5Bi%5D)
 .get

Use efficient storage for NodeRefs in DefaultLowLevelBinding