view src/treecms/memory/OnMemoryMonotonicTreeNode.java @ 25:c1e7ec6b3d44

commit
author Shoshi TAMAKI <shoshi@cr.ie.u-ryukyu.ac.jp>
date Tue, 12 Jul 2011 14:39:35 +0900
parents 68021f7091e1
children 9cb971a68cc5
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 treecms.api.MonotonicTreeNode;
import treecms.api.Node;
import treecms.api.NodeAttributes;
import treecms.api.NodeID;
import treecms.tree.util.LockableNodeTable;
import treecms.tree.util.NodeData;

public class OnMemoryMonotonicTreeNode implements MonotonicTreeNode
{
	private volatile OnMemoryMonotonicTreeNode m_parent;
	private OnMemoryNode m_node;
	private final LockableNodeTable m_table;
	
	public OnMemoryMonotonicTreeNode(OnMemoryNode _node,OnMemoryMonotonicTreeNode _parent,LockableNodeTable _table)
	{
		m_node = _node;
		m_table = _table;
		m_parent = _parent;
	}
	
	@Override
	public NodeID getID()
	{
		OnMemoryNode n = (OnMemoryNode)getNode();
		return n.getID();
	}

	@Override
	public MonotonicTreeNode getParent()
	{
		if(m_parent == null){
			return null;
		}
		
		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)
	{
		OnMemoryNode node = (OnMemoryNode)getNode();
		return node.get(_key);
	}

	@Override
	public NodeAttributes getAll()
	{
		OnMemoryNode node = (OnMemoryNode)getNode();
		return node.getAll();
	}

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

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

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

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

	@Override
	public void clearAttributes()
	{
		OnMemoryNode n = (OnMemoryNode)getNode();
		NodeData<Node> d = new NodeData<Node>(n,n);
		d.clearAttributes();
		
		cloneAndTransmit(d);
	}
	
	public void cloneAndTransmit(NodeData<Node> _d)
	{
		String fid = m_node.getID().getFamilyID();
		
		m_table.lock(fid);
		
		OnMemoryNode node = (OnMemoryNode)m_table.tip(fid);
		NodeID newID = node.getID().update();
		OnMemoryNode clone = new OnMemoryNode(newID,_d);
		m_table.register(clone);
		
		m_table.unlock(fid);
		
		OnMemoryMonotonicTreeNode parent = (OnMemoryMonotonicTreeNode)getParent();
		if(parent != null){ 
			parent.transmit(node,clone);
		}
		
		m_node = clone;
	}
	
	public boolean transmit(Node _orig,Node _edit)
	{
		String fid = m_node.getID().getFamilyID();
		m_table.lock(fid);
		OnMemoryNode node = (OnMemoryNode)getNode();
		
		NodeData<Node> d = new NodeData<Node>(node,node);
		d.replace(_edit);
		NodeID newID = node.getID().update();
		OnMemoryNode clone = new OnMemoryNode(newID,d);
		
		m_table.register(clone);
		m_table.unlock(fid);
		
		m_node = clone;
		
		OnMemoryMonotonicTreeNode parent = (OnMemoryMonotonicTreeNode)getParent();
		if(parent != null){
			return m_parent.transmit(node,clone);
		}
		return true;
	}
	
	@Override
	public Node getNode()
	{
		return m_node;
	}
	
	@Override
	public List<MonotonicTreeNode> getList()
	{
		//NodeのリストよりMonotonicTreeNodeのリストを作成する.
		OnMemoryNode node = (OnMemoryNode)getNode();
		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();
			OnMemoryMonotonicTreeNode tn = new OnMemoryMonotonicTreeNode(n,this,m_table);
			list.add(tn);
		}
		
		return Collections.unmodifiableList(list);
	}
	
	@Override
	public MonotonicTreeNode remove(int _index)
	{
		OnMemoryNode n = (OnMemoryNode)getNode();
		NodeData<Node> d = new NodeData<Node>(n,n);
		OnMemoryNode deleted = (OnMemoryNode)d.remove(_index);
		
		if(deleted != null){
			cloneAndTransmit(d);
			
			OnMemoryMonotonicTreeNode tn = new OnMemoryMonotonicTreeNode(deleted,null,m_table);
			return tn;
		}
		
		return null;
	}
	
	@Override
	public void clearChildren()
	{
		OnMemoryNode node = (OnMemoryNode)getNode();
		if(node.getList().size() == 0){
			return;
		}
		
		NodeData<Node> d = new NodeData<Node>(node,node);
		d.clearChildren();
		
		cloneAndTransmit(d);
	}

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

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

	@Override
	public MonotonicTreeNode get(int _index)
	{
		OnMemoryNode node = (OnMemoryNode)getNode();
		OnMemoryMonotonicTreeNode tn = new OnMemoryMonotonicTreeNode(node,this,m_table);
		return tn;
	}

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

	@Override
	public boolean swap(String _fid1,String _fid2)
	{
		OnMemoryNode node = (OnMemoryNode)getNode();
		NodeData<Node> d = new NodeData<Node>(node,node);
		
		if(d.swap(_fid1,_fid2)){
			cloneAndTransmit(d);
			
			return true;
		}
		
		return false;
	}

	@Override
	public Set<String> getFamilyIDSet()
	{
		Set<String> fids = m_node.getFamilyIDSet();
		return fids;
	}

	@Override
	public MonotonicTreeNode get(String _fid)
	{
		OnMemoryNode node = (OnMemoryNode)m_node.get(_fid);
		OnMemoryMonotonicTreeNode mono = new OnMemoryMonotonicTreeNode(node,this,m_table);
		return mono;
	}

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

	@Override
	public MonotonicTreeNode create(NodeAttributes _attr)
	{
		NodeID newID = getNode().getID().create();
		OnMemoryNode newNode = new OnMemoryNode(newID,new NodeData<Node>(null,_attr));
		m_table.register(newNode);
		
		OnMemoryNode thisNode = (OnMemoryNode)getNode();
		NodeData<Node> d = new NodeData<Node>(thisNode,thisNode);
		d.add(newNode);
		cloneAndTransmit(d);
		
		OnMemoryMonotonicTreeNode tn = new OnMemoryMonotonicTreeNode(newNode,this,m_table);
		return tn;
	}
	
	@Override
	public String toString()
	{
		return m_node.toString();
	}
}