Mercurial > hg > Members > shoshi > TreeCMSv2
view src/treecms/memory/OnMemoryMonotonicTreeNode.java @ 21:f3150b37f9be
commit
author | shoshi |
---|---|
date | Mon, 06 Jun 2011 21:49:04 +0900 |
parents | 084de6909451 |
children | fa784faafc78 |
line wrap: on
line source
package treecms.memory; import java.nio.ByteBuffer; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; 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 Node m_node; private static final AtomicReferenceFieldUpdater<OnMemoryMonotonicTreeNode,OnMemoryMonotonicTreeNode> m_parentUpdater = AtomicReferenceFieldUpdater.newUpdater(OnMemoryMonotonicTreeNode.class,OnMemoryMonotonicTreeNode.class,"m_parent"); private OnMemoryMonotonicTreeNode m_parent; private final Map<String,OnMemoryMonotonicTreeNode> m_cache; public OnMemoryMonotonicTreeNode(OnMemoryNode _target,OnMemoryMonotonicTreeNode _parent) { m_node = _target; m_parent = _parent; m_cache = new ConcurrentHashMap<String,OnMemoryMonotonicTreeNode>(); } @Override public NodeID getID() { return m_node.getID(); } @Override public Forest getForest() { return m_node.getForest(); } @Override public MonotonicTreeNode getParent() { return m_parent; } @Override public ByteBuffer get(ByteBuffer _key) { return m_node.get(_key); } @Override public NodeAttributes getAll() { return m_node.getAll(); } @Override public synchronized void put(ByteBuffer _key, ByteBuffer _value) { NodeData<Node> d = new NodeData<Node>(m_node,m_node); d.put(_key,_value); cloneAndTransmit(d); } @Override public synchronized void putAll(NodeAttributes _map) { NodeData<Node> d = new NodeData<Node>(m_node,m_node); d.putAll(_map); cloneAndTransmit(d); } @Override public synchronized void remove(ByteBuffer _key) { NodeData<Node> d = new NodeData<Node>(m_node,m_node); d.remove(_key); cloneAndTransmit(d); } @Override public synchronized void removeAll(Set<ByteBuffer> _keys) { NodeData<Node> d = new NodeData<Node>(m_node,m_node); d.removeAll(_keys); cloneAndTransmit(d); } @Override public synchronized void clearAttributes() { NodeData<Node> d = new NodeData<Node>(m_node,m_node); d.clearAttributes(); cloneAndTransmit(d); } public synchronized void cloneAndTransmit(NodeData<Node> _d) { OnMemoryForest f = (OnMemoryForest)m_node.getForest(); Node clone = f.createNode(m_node.getID().update(),_d); transmit(m_node,clone); m_node = clone; } public synchronized void transmit(Node _orig,Node _edit) { OnMemoryForest f = (OnMemoryForest)m_node.getForest(); OnMemoryNode clone = f.createNode(m_node.getID().update(),null); clone.replace(_edit); if(m_parent != null){ m_parent.transmit(m_node,(OnMemoryNode)clone); return; } } private synchronized OnMemoryMonotonicTreeNode getCache(OnMemoryNode _node) { NodeID id = _node.getID(); OnMemoryMonotonicTreeNode mono; synchronized(m_cache){ mono = m_cache.get(id); if(mono == null){ //cache not found . create it mono = new OnMemoryMonotonicTreeNode(_node,this); } } return mono; } @Override public synchronized Node getNode() { return m_node; } @Override public synchronized List<MonotonicTreeNode> getList() { //NodeのリストよりMonotonicTreeNodeのリストを作成する. NodeChildren<MonotonicTreeNode> res = new NodeChildrenImpl<MonotonicTreeNode>(); for(Iterator<Node> it = m_node.getList().iterator();it.hasNext();){ OnMemoryNode n = (OnMemoryNode)it.next(); res.add(getCache(n)); } return res.getList(); } @Override public synchronized boolean add(MonotonicTreeNode _n) { OnMemoryMonotonicTreeNode mono = (OnMemoryMonotonicTreeNode)_n; NodeData<Node> d = new NodeData<Node>(m_node,m_node); boolean ret = d.add(mono.m_node); if(ret){ cloneAndTransmit(d); } return ret; } @Override public synchronized boolean addAll(NodeChildren<MonotonicTreeNode> _list) { //MotonicTreeNodeのリストからNodeのリストを作成する. NodeChildren<Node> c = new NodeChildrenImpl<Node>(); for(Iterator<MonotonicTreeNode> it = _list.getList().iterator();it.hasNext();){ OnMemoryMonotonicTreeNode mono = (OnMemoryMonotonicTreeNode)it.next(); c.add(mono.m_node); } NodeData<Node> d = new NodeData<Node>(m_node,m_node); boolean ret = d.addAll(c); if(ret){ cloneAndTransmit(d); } return ret; } @Override public synchronized MonotonicTreeNode remove(int _index) { NodeData<Node> d = new NodeData<Node>(m_node,m_node); OnMemoryNode n = (OnMemoryNode) d.remove(_index); if(n != null){ cloneAndTransmit(d); return new OnMemoryMonotonicTreeNode((OnMemoryNode)n,null); } return null; } @Override public synchronized void clearChildren() { NodeData<Node> d = new NodeData<Node>(m_node,m_node); d.clearChildren(); cloneAndTransmit(d); } @Override public Map<ByteBuffer, ByteBuffer> asMap() { return m_node.asMap(); } @Override public Set<ByteBuffer> getKeySet() { return m_node.getKeySet(); } @Override public synchronized MonotonicTreeNode get(int _index) { OnMemoryNode n = (OnMemoryNode) m_node.get(_index); return getCache(n); } @Override public synchronized MonotonicTreeNode replace(MonotonicTreeNode _newChild) { OnMemoryMonotonicTreeNode mono = (OnMemoryMonotonicTreeNode)_newChild; NodeData<Node> d = new NodeData<Node>(m_node,m_node); OnMemoryNode n = (OnMemoryNode) d.replace(mono.m_node); if(n != null){ cloneAndTransmit(d); return new OnMemoryMonotonicTreeNode(n,null); } return null; } @Override public boolean contains(NodeID _id) { return m_node.contains(_id); } @Override public boolean swap(String _fid1,String _fid2) { return m_node.swap(_fid1,_fid2); } @Override public Set<String> getFamilyIDSet() { return m_node.getFamilyIDSet(); } @Override public synchronized MonotonicTreeNode get(String _fid) { OnMemoryNode n = (OnMemoryNode) m_node.get(_fid); OnMemoryMonotonicTreeNode mono = getCache(n); return mono; } @Override public synchronized MonotonicTreeNode remove(String _fid) { NodeData<Node> d = new NodeData<Node>(m_node,m_node); OnMemoryNode n = (OnMemoryNode) d.remove(_fid); cloneAndTransmit(d); return new OnMemoryMonotonicTreeNode(n,null); } }