view src/treecms/memory/OnMemoryTree.java @ 4:f5ed85be5640

finished treecms.cassandra.v1 implementation (not tested yet)
author shoshi
date Thu, 24 Feb 2011 21:30:18 +0900
parents 5fa718b63cd5
children 12604eb6b615
line wrap: on
line source

package treecms.memory;

import java.util.LinkedList;
import java.util.concurrent.ConcurrentHashMap;

import treecms.api.Forest;
import treecms.api.Node;
import treecms.api.NodeData;
import treecms.api.NodeID;
import treecms.api.Tree;
import treecms.tree.util.PreorderTreewalker;

public class OnMemoryTree implements Tree
{
	OnMemoryNode m_root;
	OnMemoryForest m_forest;
	ConcurrentHashMap<String,OnMemoryNode> m_table;
	
	public OnMemoryTree(OnMemoryNode _newRoot,OnMemoryForest _forest)
	{
		m_root = _newRoot;
		m_forest = _forest;
		
		m_table = new ConcurrentHashMap<String,OnMemoryNode>();
		for(Node elem : new PreorderTreewalker(m_root)){
			m_table.put(elem.getID().getUUID(),(OnMemoryNode)elem);
		}
	}
	
	@Override
	public Forest getForest()
	{
		return m_forest;
	}

	@Override
	public NodeID getID()
	{
		return m_root.getID();
	}

	@Override
	public NodeData getData()
	{
		return m_root.getData();
	}

	@Override
	public Node getNodeByUUID(String _uuid)
	{
		return m_table.get(_uuid);
	}

	@Override
	public synchronized Node updateTree(Node _target,NodeData _newData)
	{
		LinkedList<OnMemoryNode> path = findAndClone(m_root,(OnMemoryNode)_target,_newData);
		
		if(path == null)
		{
			//not found.
			return null;
		}
		
		m_root = path.peekFirst();
		return path.peekLast();
	}
	
	OnMemoryNode cloneNode(OnMemoryNode _target,NodeData _newData)
	{
		OnMemoryNode clone = m_forest.createNode(_target.getID().update(),_newData);
		m_table.put(clone.getID().getUUID(),clone);
		return clone;
	}
	
	LinkedList<OnMemoryNode> findAndClone(OnMemoryNode _parent,OnMemoryNode _target,NodeData _newData)
	{
		if(_parent.getID().isFamily(_target.getID())){
			//find.
			LinkedList<OnMemoryNode> path = new LinkedList<OnMemoryNode>();
			OnMemoryNode clone = cloneNode((OnMemoryNode)_parent,_newData);
			path.addFirst(clone);
			return path;
		}
		
		for(Node child : _parent.getData().list()){
			LinkedList<OnMemoryNode> path = findAndClone((OnMemoryNode)child,_target,_newData);
			if(path != null){
				OnMemoryNode clone = cloneNode((OnMemoryNode)_parent,null);
				clone.getData().list().remove(child);
				clone.getData().list().add(path.peekFirst());
				path.addFirst(clone);
				return path;
			}
		}
		
		return null; //not found.
	}

	@Override
	public Node getRoot()
	{
		return m_root;
	}

}