# HG changeset patch # User shoshi # Date 1305052441 -32400 # Node ID fbbb7e414346cb94d1b047f99e6d9fdbad2f4ec1 # Parent 85061e874775aa819582a6476400d639c0b2f7ef modified OnMemoryNode,OnMemoryTreeNode,OnMemoryMonotonicTreeNode diff -r 85061e874775 -r fbbb7e414346 CHANGELOG --- a/CHANGELOG Fri May 06 00:42:57 2011 +0900 +++ b/CHANGELOG Wed May 11 03:34:01 2011 +0900 @@ -25,16 +25,36 @@ TODO + +2011-05-10 + MonotonicTreeNodeのAPI合わせをやった. + OnMemoryの実装に移ろう.実際はOnMemoryがキャッシュとして使いやすいようにしないといけないんだけどな.AbstractHogehogeとかみたいに, + フレームワーク的に使いたいね. + +2011-05-09 + Node自体はSingleLinkedNodeである,あるNodeを頂点とするTreeを作ることで、SingleLinkedNodeをラップしたDoubleLinkedNodeを作る. + これをTreeNodeとする. + Nodeからchildrenをとるときは防御的コピーをしよう. + いろいろと気にし過ぎな気もする + + NodeDataを実装に合わせた. + 次はTreeNodeをあわせていくといいと思う. + +2011-05-07 + Nodeの子供Listは重複要素を許可しないリストなので、NodeData、SetUniqueListにする。 + NodeDataをSetUniqueListに変更した。 + NodeDataってtreecms.apiよりはtreecms.utilの方なんじゃないかと思う、なので移動します。 2011-05-05 APIを変更した、ノードを表すクラスは[Node,TreeNode,MonotonicTreeNode]の3つで,TreeNodeとMonotonicTreeNodeはNodeを継承しない。 TreeNodeとMonotonicTreeNodeもノードを表すクラスの一つであるが,継承ではなくNodeを内部にメンバーとして持つ, 問題点は,TreeNodeとMonotonicTreeNodeのメソッドをNodeとAPIの定義を用いて一致させたいが出来ない,NodeのAPIを変更するときには3つ全部書き換える必要がある. + Genericsを使って無理やり出来る方法を考えたが、まあどうだろう・・・ 現段階でNodeのメソッドは - 属性関係が get,getAll,put,putAll,remove,removeAll - 子供関係が add,addAll + 属性関係が get,getAll,put,putAll,remove,removeAll,clear + 子供関係が getChildren,addChild,addChildren,removeChild,removeChildren,clearChildren その他 getID これをinterface Nodeに記述しておいた.TreeNodeとMonotonicTreeNode interfaceの変更が必要. \ No newline at end of file diff -r 85061e874775 -r fbbb7e414346 src/treecms/api/MonotonicTreeNode.java --- a/src/treecms/api/MonotonicTreeNode.java Fri May 06 00:42:57 2011 +0900 +++ b/src/treecms/api/MonotonicTreeNode.java Wed May 11 03:34:01 2011 +0900 @@ -1,20 +1,44 @@ package treecms.api; import java.nio.ByteBuffer; +import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; +/** + * NodeのDoubleLinkedな実装です.SingleLinkedとは違いNodeの親情報まで保持します. + * TreeNodeとは違い、この実装は木を非破壊的に編集します. + * @author shoshi + */ public interface MonotonicTreeNode { - public NodeID getID(); - + /* + * 属性関連のメソッド + */ public ByteBuffer get(ByteBuffer _key); public Map getAll(); public void put(ByteBuffer _key,ByteBuffer _value); public void putAll(Map _map); - public void add(TreeNode _n); - public void addAll(List _list); + public void remove(ByteBuffer _key); + public void removeAll(Set _keys); + public void clear(); + /* + * 子供関連のメソッド + */ + public Iterator getChildren(); + public void addChild(MonotonicTreeNode _n); + public void addChildren(List _list); + public void removeChild(MonotonicTreeNode _n); + public void removeChildren(List _list); + public void clearChildren(); + + /* + * 親関連のメソッド + */ + public NodeID getID(); + public Forest getForest(); public MonotonicTreeNode getParent(); - public TreeNode getNode(); + public Node getNode(); } diff -r 85061e874775 -r fbbb7e414346 src/treecms/api/Node.java --- a/src/treecms/api/Node.java Fri May 06 00:42:57 2011 +0900 +++ b/src/treecms/api/Node.java Wed May 11 03:34:01 2011 +0900 @@ -1,12 +1,20 @@ package treecms.api; +import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; import java.nio.ByteBuffer; /** * 木構造の基本のデータ単位であるNodeを示します.Nodeは子供のリストとデータのマップを保持します.また,クライアントはノードが保持しているデータをNodeDataとして * 取得することが出来ます. + * + * NodeはSingleLinkで子供Nodeへのパスしか保持していません、どのNodeが親かどうか判断するのは不可能です. + * このようにしたのは,非破壊的木構造を実装するに当たり,編集対象のNodeの親を検索するのが困難であるからです. + * DoubleLinkな実装はTree/MonotonicTreeで行います. + * + * また,重複した子供を追加することは出来ません,このインターフェイスを実装するクラスはそのように実装します. * @author shoshi */ public interface Node @@ -19,6 +27,7 @@ /** * Nodeが保持するデータを取得します.クライアントはこのメソッドを用いて取得されるNodeDataを用いてNodeの内容を変更できません。 + * 変更を加えた場合は無視されるか、例外が発生します. * @return Nodeが保持するNodeData */ public NodeData getData(); @@ -29,17 +38,10 @@ */ public Forest getForest(); - /** - * 子供Nodeのリストを取得します.. - * @return 子供Nodeのリスト + /* + * 属性関連のメソッド + * get,getAll,put,putAll,remove,removeAll,clear */ - public List children(); - - /** - * このNodeが保持するデータをマップとしてすべて取得します. - * @return Nodeが保持するすべてのデータのマップ - */ - public Map getAll(); /** * このNodeが保持する値の中で指定されたキーと対応する値を取得します. @@ -49,28 +51,10 @@ public ByteBuffer get(ByteBuffer _key); /** - * 指定されたリストに含まれるNodeを,すべて子供Nodeとして追加します. - * @param _children 追加される子供Nodeを保持するリスト - */ - public void addAll(List _children); - - /** - * 指定されたNodeを子供Nodeとして追加します. - * @param _child + * このNodeが保持するデータをマップとしてすべて取得します. + * @return Nodeが保持するすべてのデータのマップ */ - public void add(Node _child); - - /** - * 指定されたNodeを削除します。 - * @param _child - */ - public void remove(Node _child); - - /** - * 指定した子供を全て削除します. - * @param _children 削除される子供 - */ - public void removeAll(List _children); + public Map getAll(); /** * キーとそれに対応する値を保存します.キーが重複した場合は上書きされます. @@ -80,14 +64,66 @@ public void put(ByteBuffer _key,ByteBuffer _value); /** + * キーとそれに対応する値を複数保持するマップを引数としてとり,マップが保持する値をすべて追加します. + * @param _map 追加される値のマップ + */ + public void putAll(Map _map); + + /** * キーとそれに対応する値を削除します。 * @param _key キー */ public void remove(ByteBuffer _key); /** - * キーとそれに対応する値を複数保持するマップを引数としてとり,マップが保持する値をすべて追加します. - * @param _map 追加される値のマップ + * Keyの集合すべてを削除します. + * @param _key + */ + public void removeAll(Set _key); + + /** + * Keyの集合全てを削除します. + */ + public void clear(); + + /* + * 子供関連 + * getChildren,addChild,addChildren,removeChild,removeChildren,clearChildren + */ + + /** + * 子供のIteratorを取得します.このIteratorは編集するためのメソッドは実装しません. + * 呼び出した場合は例外は発生します. + * @return 子供NodeのIterator + */ + public Iterator getChildren(); + + /** + * 指定されたNodeを子供Nodeとして追加します. + * @param _child */ - public void putAll(Map _map); -} \ No newline at end of file + public void addChild(Node _child); + + /** + * 指定されたリストに含まれるNodeを,すべて子供Nodeとして追加します. + * @param _children 追加される子供Nodeを保持するリスト + */ + public void addChildren(List _children); + + /** + * 指定されたNodeを削除します。 + * @param _child + */ + public void removeChild(Node _child); + + /** + * 指定した子供を全て削除します. + * @param _children 削除される子供 + */ + public void removeChildren(List _children); + + /** + * 全ての子供を削除します. + */ + public void clearChildren(); +} diff -r 85061e874775 -r fbbb7e414346 src/treecms/api/NodeData.java --- a/src/treecms/api/NodeData.java Fri May 06 00:42:57 2011 +0900 +++ b/src/treecms/api/NodeData.java Wed May 11 03:34:01 2011 +0900 @@ -1,28 +1,35 @@ package treecms.api; import java.nio.ByteBuffer; + +import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; +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.CopyOnWriteArrayList; +import org.apache.commons.collections.list.SetUniqueList; /** - * Nodeが保持するデータの集合です.Nodeを大きく変更するときや新しく作成される場合に使用されます. - * 通常このクラスのインスタンスをNodeから取得した場合,NodeDataインスタンスに変更(set,add)を加えても元のNodeに変更は反映されません. + * Node が保持するデータのスナップショットです.Node を大きく変更するときや新しく作成される場合に使用されます. + * 通常このクラスのインスタンスを Node から取得した場合,NodeData インスタンスに変更(set,add)を加えても元の Node に変更は反映されません. * その様に実装してください. + * + * このクラスは Node が保持するデータのうち 子供ノードのリスト・属性のマップ のみ保持しています.つまり,ノードが持っているはずの ID は保持していません. + * getID,getForest を呼び出すと UnsupportedOperationException をスローします. * @author shoshi */ public final class NodeData implements Node { /** - * 子供Nodeのリスト + * 子供 Node の List + * 子供 Node の List は重複する Node を許可しない. */ private List m_children; /** - * キーと対応する値のマップ + * Key と対応する Value の Map */ private Map m_attrs; @@ -35,154 +42,141 @@ } /** - * コピーコンストラクタです.NodeDataの内容を防御的にコピーします. + * コピーコンストラクタです. + * NodeData の内容を防御的にコピーします. * @param _data */ public NodeData(NodeData _data) { if(_data != null){ - m_children = new CopyOnWriteArrayList(_data.m_children); - m_attrs = new ConcurrentHashMap(_data.m_attrs); + // SetUniqueList を使用することにより,List の重複要素を許可しない. + m_children = SetUniqueList.decorate(_data.m_children); + m_attrs = new HashMap(_data.m_attrs); return; } - m_children = new CopyOnWriteArrayList(); - m_attrs = new ConcurrentHashMap(); + m_children = SetUniqueList.decorate(new ArrayList()); + m_attrs = new HashMap(); } /** * 内部でコピーコンストラクタを呼び出します. - * @return このNodeDataのコピー + * @return この NodeData のコピー */ public NodeData deepCopy() { return new NodeData(this); } - /** - * キーのセットを取得します. - * @return キーのセット - */ - public Set keySet() - { - return m_attrs.keySet(); - } - - /** - * キーに対応する値を取得します. - * @param _name - * @return キーに対応する値 - */ - public ByteBuffer get(ByteBuffer _name) - { - return m_attrs.get(_name); - } - - /** - * キーとそれに対応する値を追加します. - * @param _name キー - * @param _value 値 - */ - public void put(ByteBuffer _name,ByteBuffer _value) - { - m_attrs.put(_name,_value); - } - - /** - * キーとその対応する値をマップから削除します - * @param _name - */ - public void remove(ByteBuffer _name) - { - m_attrs.remove(_name); - } - - /** - * キーとそれに対応する値のマップ全体を追加します. - * @param _map - */ - public void putAll(Map _map) - { - m_attrs.putAll(_map); - } - - /** - * 子供Nodeのリストを取得します.
- * この取得されたリストは編集できません.編集はadd,addAllより行ってください. - * @return 子供Nodeのリスト - */ - public List children() - { - return Collections.unmodifiableList(m_children); - } - - /** - * 子供Nodeを追加します. - * @param _child - */ - public void add(Node _child) - { - m_children.add(_child); - } - - /** - * 子供Nodeリスト全部を子供Nodeとして追加します. - * @param _child - */ - public void addAll(List _child) - { - m_children.addAll(_child); - } - - /** - * 指定されたNodeを子供Nodeのリストから削除します. - * @param _child - */ - public void remove(Node _child) - { - m_children.remove(_child); - } - - /** - * 指定されたNodeのリストに含まれるすべてのNodeを子供Nodeのリストから削除します. - * @param _child - */ - public void removeAll(List _child) - { - m_children.removeAll(_child); - } - - /** - * NodeDataが保持しているすべてのキーと値の組のマップを返します. - * @return すべてのキーと値のマップ - */ - public Map getAll() - { - return Collections.unmodifiableMap(m_attrs); - } - - /** - * 子供Nodeのリストをクリアします.(すべて削除します.) - */ - public void clear() - { - m_children.clear(); - } - @Override public NodeID getID() { + //このクラスはデータのみ保持する. return null; } @Override public NodeData getData() { - return this; + return new NodeData(this); } @Override public Forest getForest() { + //このクラスはデータのみ保持する. return null; } + + /* + * 属性関連 + */ + + public Set keySet() + { + return m_attrs.keySet(); + } + + @Override + public ByteBuffer get(ByteBuffer _name) + { + return m_attrs.get(_name); + } + + @Override + public Map getAll() + { + return Collections.unmodifiableMap(this.m_attrs); + } + + @Override + public void put(ByteBuffer _name,ByteBuffer _value) + { + m_attrs.put(_name,_value); + } + + @Override + public void putAll(Map _map) + { + m_attrs.putAll(_map); + } + + @Override + public void remove(ByteBuffer _name) + { + m_attrs.remove(_name); + } + + @Override + public void removeAll(Set _keySet) + { + for(ByteBuffer _key : _keySet){ + m_attrs.remove(_key); + } + } + + @Override + public void clear() + { + m_attrs.clear(); + } + + /* + * 子供関連 + */ + + @Override + public Iterator getChildren() + { + return Collections.unmodifiableList(m_children).iterator(); + } + + @Override + public void addChild(Node _child) + { + m_children.add(_child); + } + + @Override + public void addChildren(List _child) + { + m_children.addAll(_child); + } + + @Override + public void removeChild(Node _child) + { + m_children.remove(_child); + } + + @Override + public void removeChildren(List _child) + { + m_children.removeAll(_child); + } + + @Override + public void clearChildren() + { + m_children.clear(); + } } diff -r 85061e874775 -r fbbb7e414346 src/treecms/api/TreeNode.java --- a/src/treecms/api/TreeNode.java Fri May 06 00:42:57 2011 +0900 +++ b/src/treecms/api/TreeNode.java Wed May 11 03:34:01 2011 +0900 @@ -1,25 +1,50 @@ package treecms.api; import java.nio.ByteBuffer; +import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; +/** + * DoubleLinkedなNodeの実装です.SingleLinkedなNodeの実装と違い,親の情報を保持します. + * 非破壊的木構造の実装では,Nodeは子どもの情報しか持っていません.これは,一つのNodeに対して複数の親が存在するためです. + * 木構造内のあるNodeへのRootNodeからのパスを検索する手間を省くことが出来ます. + * + * なのでSingleLinkedとDoubleLinkedを分けて,DoubleLinkedはSingleLinkedを内包した形で実装します. + * TreeNodeがNodeのインターフェイスを継承していないのは,継承するとSingleLinkedなNodeに子供として追加できるようになるからです. + * + * また,TreeNodeを編集したときは非破壊的に編集されず、破壊的に編集されます. + * @author shoshi + */ public interface TreeNode { - public NodeID getID(); - + /* + * 属性関連のメソッド + */ public ByteBuffer get(ByteBuffer _key); public Map getAll(); public void put(ByteBuffer _key,ByteBuffer _value); public void putAll(Map _map); public void remove(ByteBuffer _key); - public void removeKeys(List _keys); + public void removeAll(Set _keys); + public void clear(); - public void add(TreeNode _n); - public void addAll(List _list); - public void remove(TreeNode _n); - public void removeAll(List _list); + /* + * 子供関連のメソッド + */ + public Iterator getChildren(); + public void addChild(TreeNode _n); + public void addChildren(List _list); + public void removeChild(TreeNode _n); + public void removeChildren(List _list); + public void clearChildren(); + /* + * 親関連のメソッド + */ + public NodeID getID(); + public Forest getForest(); public TreeNode getParent(); public Node getNode(); } diff -r 85061e874775 -r fbbb7e414346 src/treecms/memory/OnMemoryMonotonicTreeNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/treecms/memory/OnMemoryMonotonicTreeNode.java Wed May 11 03:34:01 2011 +0900 @@ -0,0 +1,206 @@ +package treecms.memory; + +import java.nio.ByteBuffer; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import treecms.api.Forest; +import treecms.api.MonotonicTreeNode; +import treecms.api.Node; +import treecms.api.NodeID; +import treecms.api.TreeNode; + +/** + * SingleLinkedなNodeをラップしたDoubleLinkedなNodeの実装です. + * @author shoshi + */ +public class OnMemoryMonotonicTreeNode implements MonotonicTreeNode +{ + private OnMemoryMonotonicTree m_tree; + private OnMemoryNode m_node; + private OnMemoryMonotonicTreeNode m_parent; + + /** + * コンストラクタです. + * @param _target 対象となるSingleLinked Node + * @param _parent このDoubleLinked Nodeの親,RootNodeならnull + * @param _tree このNodeがRootNodeなら,nullではいけない. + */ + public OnMemoryMonotonicTreeNode(OnMemoryNode _target,OnMemoryMonotonicTreeNode _parent,OnMemoryMonotonicTree _tree) + { + if(_target == null){ + throw new NullPointerException("_target must not be null."); + } + + if(_parent == null && _tree == null){ + throw new NullPointerException("_parent or _tree must not be null."); + } + + m_node = _target; + m_parent = _parent; + m_tree = _tree; + } + + /* + * 親関連のメソッド + */ + + @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 Node getNode() + { + return m_node; + } + + /* + * 属性関連のメソッド + */ + + @Override + public ByteBuffer get(ByteBuffer _key) + { + return m_node.get(_key); + } + + @Override + public Map getAll() + { + return m_node.getAll(); + } + + @Override + public void put(ByteBuffer _key, ByteBuffer _value) + { + m_node.put(_key,_value); + } + + @Override + public void putAll(Map _map) + { + m_node.putAll(_map); + } + + @Override + public void remove(ByteBuffer _key) + { + m_node.remove(_key); + } + + @Override + public void removeAll(Set _keys) + { + m_node.removeAll(_keys); + } + + @Override + public void clear() + { + m_node.clear(); + } + + /** + * このMonotonicNodeに変更が加えられたら,こちらのメソッドが呼び出されます. + * このメソッドでは非破壊的に変更するために,SingleLinkedNodeのクローンを作成し, + * 親にも複製を依頼します. + * + * RootNodeまで伝搬すると親のNodeはnullとなる.親Nodeは担当するMonotonicTreeのオブジェクトを保持しており,そこにRootNodeが変更されたことを通知する. + * 通知が終わり,処理が戻ってきた時に自身のOnMemoryNodeをクローンした新しいものに書き換えます. + * + * _fromがnullの場合は,自身が編集元であることを示します. + * @param _from 編集元のOnMemoryMonotonicTreeNode + */ + public void cloneAndTransmit(OnMemoryNode _from) + { + OnMemoryNode clone = m_node.cloneNode(); + if(m_parent != null){ + //親が存在する,親に変更があったことを伝搬する. + m_parent.cloneAndTransmit(clone); + }else{ + //何かすることはないかな + } + + //編集終了 + m_node = clone; + } + + /* + * 子供関連のメソッド + */ + + @Override + public Iterator getChildren() + { + //NodeのリストよりMonotonicTreeNodeのリストを作成する. + LinkedList res = new LinkedList(); + for(Iterator it = m_node.getChildren();it.hasNext();){ + OnMemoryNode n = (OnMemoryNode)it.next(); + res.add(new OnMemoryMonotonicTreeNode(n,this,null)); + } + + return res.iterator(); + } + + @Override + public void addChild(MonotonicTreeNode _n) + { + m_node.addChild(_n.getNode()); + } + + @Override + public void addChildren(List _list) + { + //MotonicTreeNodeのリストからNodeのリストを作成する. + LinkedList res = new LinkedList(); + for(Iterator it = _list.iterator();it.hasNext();){ + MonotonicTreeNode mono = (MonotonicTreeNode)it.next(); + res.add(mono.getNode()); + } + + m_node.addChildren(res); + } + + @Override + public void removeChild(MonotonicTreeNode _n) + { + m_node.removeChild(_n.getNode()); + } + + @Override + public void removeChildren(List _list) + { + //MonotonicTreeNodeのリスト + LinkedList res = new LinkedList(); + for(Iterator it = _list.iterator();it.hasNext();){ + MonotonicTreeNode mono = it.next(); + res.add(mono.getNode()); + } + + m_node.removeChildren(res); + } + + @Override + public void clearChildren() + { + m_node.clearChildren(); + } + +} diff -r 85061e874775 -r fbbb7e414346 src/treecms/memory/OnMemoryNode.java --- a/src/treecms/memory/OnMemoryNode.java Fri May 06 00:42:57 2011 +0900 +++ b/src/treecms/memory/OnMemoryNode.java Wed May 11 03:34:01 2011 +0900 @@ -1,8 +1,11 @@ package treecms.memory; import java.nio.ByteBuffer; +import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; + import treecms.api.Forest; import treecms.api.Node; import treecms.api.NodeData; @@ -20,7 +23,7 @@ private NodeData m_data; /** - * コンストラクタです. + * コンストラクタ * @param _forest このNodeが属するForestです. * @param _id このNodeのNodeIDです. * @param _newData このNodeに割り当てるNodeDataです.防御的にコピーします. @@ -32,122 +35,97 @@ m_data = (_newData != null) ? _newData.deepCopy() : new NodeData(); } - /** - * Nodeが属するForestを取得します. - * @return Nodeが属するForest + /* + * Nodeの情報関連 */ + @Override public Forest getForest() { return m_forest; } - /** - * Nodeに対応するNodeIDを取得します. - * @return Nodeに対応するNodeID - */ @Override public NodeID getID() { return m_id; } - /** - * Nodeが保持するデータを取得します.クライアントはこのメソッドを用いて取得されるNodeDataを用いてNodeの内容を変更できません。 - * @return Nodeが保持するNodeData - */ @Override public NodeData getData() { return m_data.deepCopy(); } - - /** - * 指定されたNodeを子供Nodeとして追加します. - * @param _child + + /* + * 子供関連のメソッド */ + @Override - public void add(Node _child) + public Iterator getChildren() { - m_data.add(_child); - } - - /** - * 子供Nodeを削除します。 - * @param _child - */ - @Override - public void remove(Node _child) - { - m_data.remove(_child); + //Iteratorが変更不可なので、そのまま渡しても構わない + return m_data.getChildren(); } - /** - * 指定されたリストに含まれるNodeを,すべて子供Nodeとして追加します. - * @param _children 追加される子供Nodeを保持するリスト - */ + @Override + public void addChild(Node _child) + { + m_data.addChild(_child); + } + + @Override + public void addChildren(List _child) + { + m_data.addChildren(_child); + } + @Override - public void addAll(List _children) + public void removeChild(Node _child) + { + m_data.removeChild(_child); + } + + @Override + public void removeChildren(List _children) { - m_data.addAll(_children); + m_data.removeChildren(_children); + } + + @Override + public void clearChildren() + { + m_data.clearChildren(); } - /** - * 子供Nodeのリストを取得します.. - * @return 子供Nodeのリスト + /* + * 要素関連のメソッド */ - @Override - public List children() - { - return m_data.children(); - } - /** - * このNodeが保持する値の中で指定されたキーと対応する値を取得します. - * @param _key データに対応するキー - * @return キーと対応する値,見つからない場合はnull - */ @Override public ByteBuffer get(ByteBuffer _key) { return m_data.get(_key); } - /** - * このNodeが保持するデータをマップとしてすべて取得します. - * @return Nodeが保持するすべてのデータのマップ - */ @Override public Map getAll() { return m_data.getAll(); } - /** - * キーとそれに対応する値を保存します.キーが重複した場合は上書きされます. - * @param _key キー - * @param _value 値 - */ @Override public void put(ByteBuffer _key, ByteBuffer _value) { m_data.put(_key,_value); } - /** - * キーとそれに対応する値を複数保持するマップを引数としてとり,マップが保持する値をすべて追加します. - * @param _map 追加される値のマップ - */ @Override public void putAll(Map _map) { m_data.putAll(_map); } - /** - * キーとそれに対応する値を削除します。 - * @param _key キー - */ @Override public void remove(ByteBuffer _key) { @@ -155,6 +133,24 @@ } @Override + public void removeAll(Set _keySet) + { + m_data.removeAll(_keySet); + } + + @Override + public void clear() + { + m_data.clear(); + } + + @Override + public int hashCode() + { + return m_id.hashCode(); + } + + @Override public String toString() { return getID().toString(); diff -r 85061e874775 -r fbbb7e414346 src/treecms/memory/OnMemoryTree.java --- a/src/treecms/memory/OnMemoryTree.java Fri May 06 00:42:57 2011 +0900 +++ b/src/treecms/memory/OnMemoryTree.java Wed May 11 03:34:01 2011 +0900 @@ -1,15 +1,6 @@ package treecms.memory; -import java.nio.ByteBuffer; -import java.util.List; -import java.util.Map; -import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; - -import treecms.api.Forest; -import treecms.api.Node; -import treecms.api.NodeData; -import treecms.api.NodeID; import treecms.api.Tree; import treecms.api.TreeNode; diff -r 85061e874775 -r fbbb7e414346 src/treecms/memory/OnMemoryTreeNode.java --- a/src/treecms/memory/OnMemoryTreeNode.java Fri May 06 00:42:57 2011 +0900 +++ b/src/treecms/memory/OnMemoryTreeNode.java Wed May 11 03:34:01 2011 +0900 @@ -1,26 +1,34 @@ package treecms.memory; import java.nio.ByteBuffer; -import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedList; import java.util.List; import java.util.Map; - -import org.apache.commons.collections.list.SetUniqueList; - +import java.util.Set; import treecms.api.Forest; import treecms.api.Node; -import treecms.api.NodeData; import treecms.api.NodeID; -import treecms.api.SingleNode; import treecms.api.TreeNode; +/** + * DoubleLinkedなNodeであるTreeNodeのOnMemory実装です. + * @author shoshi + */ public class OnMemoryTreeNode implements TreeNode { public OnMemoryTreeNode m_parent; public OnMemoryNode m_node; + /** + * コンストラクタです. + * @param _node 対象となるSingleLinkedなNode + * @param _parent 親のOnMemoryTreeNode + */ public OnMemoryTreeNode(OnMemoryNode _node,OnMemoryTreeNode _parent) { + //とりあえず、チェック if(_node == null){ throw new NullPointerException(); } @@ -31,38 +39,106 @@ m_parent = _parent; } + /* + * 親関連のメソッド + */ + @Override public NodeID getID() { return m_node.getID(); } - + @Override - public NodeData getData() + public Node getNode() { - return m_node.getData(); + return m_node; } - + + @Override + public TreeNode getParent() + { + return m_parent; + } + @Override public Forest getForest() { return m_node.getForest(); } + + /* + * 子供関連のメソッド + */ @Override - public List children() + public Iterator getChildren() { /* - * TreeNodeの子TreeNodeリストを作成する. * m_node(対象ノード)のリストにはNodeが格納されており、TreeNodeのリストを取得するためにはTreeNodeで要素を構成する必要がある. */ - List list = m_node.children(); - ArrayList ret = new ArrayList(list.size()); - for(Node n : list){ - ret.add(new OnMemoryTreeNode((OnMemoryNode)n,this)); + LinkedList ret = new LinkedList(); + for(Iterator it = m_node.getChildren();it.hasNext();){ + OnMemoryNode n = (OnMemoryNode)it.next(); + ret.add(new OnMemoryTreeNode(n,this)); + } + + return Collections.unmodifiableList(ret).iterator(); + } + + @Override + public void addChild(TreeNode _child) + { + m_node.addChild(_child.getNode()); + } + + @Override + public void addChildren(List _children) + { + /* + * TreeNodeのリストからNodeのリストへ変換する + */ + LinkedList res = new LinkedList(); + for(Iterator it = _children.iterator();it.hasNext();){ + TreeNode tn = it.next(); + res.add(tn.getNode()); } - return ret; + m_node.addChildren(res); + } + + @Override + public void removeChild(TreeNode _child) + { + m_node.removeChild(_child.getNode()); + } + + @Override + public void removeChildren(List _children) + { + LinkedList res = new LinkedList(); + for(Iterator it = _children.iterator();it.hasNext();){ + TreeNode tn = it.next(); + res.add(tn.getNode()); + } + + m_node.removeChildren(res); + } + + @Override + public void clearChildren() + { + m_node.clearChildren(); + } + + /* + * 属性関連のメソッド + */ + + @Override + public ByteBuffer get(ByteBuffer _key) + { + return m_node.get(_key); } @Override @@ -72,54 +148,32 @@ } @Override - public ByteBuffer get(ByteBuffer _key) + public void put(ByteBuffer _key,ByteBuffer _value) { - return m_node.get(_key); + m_node.put(_key,_value); } - - @Override - public void addAll(List _children) - { - } - + @Override - public void add(Node _child) { - // TODO Auto-generated method stub - + public void putAll(Map _map) + { + m_node.putAll(_map); } - - @Override - public void remove(Node _child) { - // TODO Auto-generated method stub - - } - + @Override - public void put(ByteBuffer _key, ByteBuffer _value) { - // TODO Auto-generated method stub - - } - - @Override - public void remove(ByteBuffer _key) { - } - - @Override - public void putAll(Map _map) { - // TODO Auto-generated method stub - + public void remove(ByteBuffer _key) + { + m_node.remove(_key); } - + @Override - public TreeNode getParent() { - // TODO Auto-generated method stub - return null; + public void removeAll(Set _keySet) + { + m_node.removeAll(_keySet); } - + @Override - public SingleNode getNode() { - // TODO Auto-generated method stub - return null; + public void clear() + { + m_node.clear(); } - }