view src/treecms/memory/OnMemoryMonotonicTreeNode.java @ 22:fa784faafc78

commit
author shoshi
date Tue, 07 Jun 2011 16:42:49 +0900 (2011-06-07)
parents f3150b37f9be
children 77a894c0b919
line wrap: on
line source
package treecms.memory;

import java.nio.ByteBuffer;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.FutureTask;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;

import treecms.api.Forest;
import treecms.api.MonotonicTreeNode;
import treecms.api.Node;
import treecms.api.NodeAttributes;
import treecms.api.NodeChildren;
import treecms.api.NodeID;
import treecms.tree.util.NodeChildrenImpl;
import treecms.tree.util.NodeData;

/**
 * SingleLinkedなNodeをラップしたDoubleLinkedなNodeの実装です.
 * @author shoshi
 */
public class OnMemoryMonotonicTreeNode implements MonotonicTreeNode
{
	private String m_node;
	private OnMemoryMonotonicTreeNode m_parent;
	private final OnMemoryMonotonicTree m_tree;
	private final ConcurrentMap<String,MonotonicTreeNode> m_cache;
	
	public OnMemoryMonotonicTreeNode(String _fid,OnMemoryMonotonicTreeNode _parent,OnMemoryMonotonicTree _tree)
	{
		m_node = _fid;
		m_parent = _parent;
		m_cache = new ConcurrentHashMap<String,MonotonicTreeNode>();
		m_tree = _tree;
	}
	
	@Override
	public NodeID getID()
	{
		OnMemoryNode n = m_tree.get(m_node);
		return n.getID();
	}

	@Override
	public MonotonicTreeNode getParent()
	{
		synchronized(m_parent){
			OnMemoryNode node = (OnMemoryNode)getNode();
			
			//check , does parent contain the node.
			if(!m_parent.contains(node.getID())){
				m_parent = null;
			}
			return m_parent;
		}
	}
	
	@Override
	public ByteBuffer get(ByteBuffer _key)
	{
		return m_tree.get(m_node).get(_key);
	}

	@Override
	public NodeAttributes getAll()
	{
		return m_tree.get(m_node).getAll();
	}

	@Override
	public synchronized void put(ByteBuffer _key, ByteBuffer _value)
	{
		OnMemoryNode n = m_tree.get(m_node);
		NodeData<Node> d = new NodeData<Node>(n,n);
		d.put(_key,_value);
		
		cloneAndTransmit(d);
	}

	@Override
	public synchronized void putAll(NodeAttributes _map)
	{
		OnMemoryNode n = m_tree.get(m_node);
		NodeData<Node> d = new NodeData<Node>(n,n);
		d.putAll(_map);
		
		cloneAndTransmit(d);
	}

	@Override
	public synchronized void remove(ByteBuffer _key)
	{
		OnMemoryNode n = m_tree.get(m_node);
		NodeData<Node> d = new NodeData<Node>(n,n);
		d.remove(_key);
		
		cloneAndTransmit(d);
	}

	@Override
	public synchronized void removeAll(Set<ByteBuffer> _keys)
	{
		OnMemoryNode n = m_tree.get(m_node);
		NodeData<Node> d = new NodeData<Node>(n,n);
		d.removeAll(_keys);
		
		cloneAndTransmit(d);
	}

	@Override
	public synchronized void clearAttributes()
	{
		OnMemoryNode n = m_tree.get(m_node);
		NodeData<Node> d = new NodeData<Node>(n,n);
		d.clearAttributes();
		
		cloneAndTransmit(d);
	}
	
	public synchronized void cloneAndTransmit(NodeData<Node> _d)
	{
		OnMemoryNode node = m_tree.get(m_node);
		Node clone = m_tree.createNode(node.getID().update(),_d);
		transmit(node,clone);
	}
	
	public synchronized boolean transmit(Node _orig,Node _edit)
	{
		OnMemoryNode node = m_tree.get(m_node);
		
		NodeData<Node> d = new NodeData<Node>(node,node);
		if(!d.contains(_edit.getID())){
			
		}
		d.replace(_edit);
		
		OnMemoryNode clone = m_tree.createNode(node.getID().update(),null);
		
		
		OnMemoryMonotonicTreeNode parent = (OnMemoryMonotonicTreeNode)getParent();
		if(parent != null){
			return m_parent.transmit(node,clone);
		}
		return true;
	}
	
	@Override
	public synchronized Node getNode()
	{
		return m_tree.get(m_node);
	}
	
	@Override
	public synchronized List<MonotonicTreeNode> getList()
	{
		//NodeのリストよりMonotonicTreeNodeのリストを作成する.
		OnMemoryNode node = m_tree.get(m_node);
		int size = node.getList().size();
		ArrayList<MonotonicTreeNode> list = new ArrayList<MonotonicTreeNode>(size);
		for(Iterator<Node> it = node.getList().iterator();it.hasNext();){
			OnMemoryNode n = (OnMemoryNode)it.next();
			list.add(getCache(n.getID().getFamilyID()));
		}
		
		return (List<MonotonicTreeNode>)Collections.unmodifiableCollection(list);
	}
	
	public OnMemoryMonotonicTreeNode getCache(final String _fid)
	{
		OnMemoryMonotonicTreeNode cache = new OnMemoryMonotonicTreeNode(m_node,this,m_tree);
		cache = (OnMemoryMonotonicTreeNode)m_cache.putIfAbsent(_fid,cache);
		
		return cache;
	}

	@Override
	public synchronized MonotonicTreeNode remove(int _index)
	{
		OnMemoryNode n = m_tree.get(m_node);
		NodeData<Node> d = new NodeData<Node>(n,n);
		OnMemoryNode deleted = (OnMemoryNode) d.remove(_index);
		
		if(n != null){
			cloneAndTransmit(d);
			
			OnMemoryMonotonicTreeNode tn = getCache(deleted.getID().getFamilyID());
			return tn;
		}
		
		return null;
	}
	
	@Override
	public synchronized void clearChildren()
	{
		OnMemoryNode node = m_tree.get(m_node);
		NodeData<Node> d = new NodeData<Node>(node,node);
		d.clearChildren();
		
		cloneAndTransmit(d);
	}

	@Override
	public Map<ByteBuffer, ByteBuffer> asMap()
	{
		OnMemoryNode node = m_tree.get(m_node);
		return node.asMap();
	}

	@Override
	public Set<ByteBuffer> getKeySet()
	{
		OnMemoryNode node = m_tree.get(m_node);
		return node.getKeySet();
	}

	@Override
	public synchronized MonotonicTreeNode get(int _index)
	{
		OnMemoryNode node = m_tree.get(m_node);
		return getCache(node.getID().getFamilyID());
	}

	@Override
	public boolean contains(NodeID _id)
	{
		OnMemoryNode node = m_tree.get(m_node);
		return node.contains(_id);
	}

	@Override
	public boolean swap(String _fid1,String _fid2)
	{
		OnMemoryNode node = m_tree.get(m_node);
		return node.swap(_fid1,_fid2);
	}

	@Override
	public Set<String> getFamilyIDSet()
	{
		OnMemoryNode node = m_tree.get(m_node);
		return node.getFamilyIDSet();
	}

	@Override
	public synchronized MonotonicTreeNode get(String _fid)
	{
		OnMemoryMonotonicTreeNode mono = getCache(_fid);
		return mono;
	}

	@Override
	public synchronized MonotonicTreeNode remove(String _fid)
	{
		OnMemoryMonotonicTreeNode tnode = getCache(_fid);
		OnMemoryNode node = (OnMemoryNode)tnode.getNode();
		
		NodeData<Node> d = new NodeData<Node>(node,node);
		d.remove(_fid);
		
		cloneAndTransmit(d);
		return tnode;
	}

	@Override
	public synchronized MonotonicTreeNode create(NodeAttributes _attr)
	{
		NodeID newID = getNode().getID().create();
		OnMemoryNode newNode = new OnMemoryNode(newID,new NodeData<Node>(null,_attr));
		
		OnMemoryNode thisNode = (OnMemoryNode)getNode();
		NodeData<Node> d = new NodeData<Node>(thisNode,thisNode);
		d.add(newNode);
		
		return null;
	}
}