# HG changeset patch # User shoshi # Date 1304610177 -32400 # Node ID 85061e874775aa819582a6476400d639c0b2f7ef # Parent 4e0ed81bea8947058777e69505af3baef69916e9 commit diff -r 4e0ed81bea89 -r 85061e874775 CHANGELOG --- a/CHANGELOG Tue Apr 19 19:12:16 2011 +0900 +++ b/CHANGELOG Fri May 06 00:42:57 2011 +0900 @@ -22,3 +22,19 @@ Requirements. Cassandra 0.6.x + + +TODO + +2011-05-05 + APIを変更した、ノードを表すクラスは[Node,TreeNode,MonotonicTreeNode]の3つで,TreeNodeとMonotonicTreeNodeはNodeを継承しない。 + TreeNodeとMonotonicTreeNodeもノードを表すクラスの一つであるが,継承ではなくNodeを内部にメンバーとして持つ, + + 問題点は,TreeNodeとMonotonicTreeNodeのメソッドをNodeとAPIの定義を用いて一致させたいが出来ない,NodeのAPIを変更するときには3つ全部書き換える必要がある. + + 現段階でNodeのメソッドは + 属性関係が get,getAll,put,putAll,remove,removeAll + 子供関係が add,addAll + その他 getID + + これをinterface Nodeに記述しておいた.TreeNodeとMonotonicTreeNode interfaceの変更が必要. \ No newline at end of file diff -r 4e0ed81bea89 -r 85061e874775 src/treecms/api/Forest.java --- a/src/treecms/api/Forest.java Tue Apr 19 19:12:16 2011 +0900 +++ b/src/treecms/api/Forest.java Fri May 06 00:42:57 2011 +0900 @@ -34,11 +34,11 @@ Tree getTree(Node _root); /** - * 木を非破壊的に編集するTreeEditorを取得します + * 木を非破壊的に編集するMonotonicTreeを取得します * @param _tree 対象 * @return TreeEditor */ - TreeEditor getTreeEditor(Tree _tree); + MonotonicTree getMonotonicTree(Tree _tree); /** * NodeDataを保持する新しいNodeを作成します.このメソッドで作成されるNodeは新しいUUIDを持ちます. diff -r 4e0ed81bea89 -r 85061e874775 src/treecms/api/MonotonicTreeNode.java --- a/src/treecms/api/MonotonicTreeNode.java Tue Apr 19 19:12:16 2011 +0900 +++ b/src/treecms/api/MonotonicTreeNode.java Fri May 06 00:42:57 2011 +0900 @@ -1,7 +1,20 @@ package treecms.api; +import java.nio.ByteBuffer; +import java.util.List; +import java.util.Map; + 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 MonotonicTreeNode getParent(); - public SingleNode getNode(); + public TreeNode getNode(); } diff -r 4e0ed81bea89 -r 85061e874775 src/treecms/api/Node.java --- a/src/treecms/api/Node.java Tue Apr 19 19:12:16 2011 +0900 +++ b/src/treecms/api/Node.java Fri May 06 00:42:57 2011 +0900 @@ -67,6 +67,12 @@ public void remove(Node _child); /** + * 指定した子供を全て削除します. + * @param _children 削除される子供 + */ + public void removeAll(List _children); + + /** * キーとそれに対応する値を保存します.キーが重複した場合は上書きされます. * @param _key キー * @param _value 値 diff -r 4e0ed81bea89 -r 85061e874775 src/treecms/api/NodeData.java --- a/src/treecms/api/NodeData.java Tue Apr 19 19:12:16 2011 +0900 +++ b/src/treecms/api/NodeData.java Fri May 06 00:42:57 2011 +0900 @@ -14,7 +14,7 @@ * その様に実装してください. * @author shoshi */ -public final class NodeData +public final class NodeData implements Node { /** * 子供Nodeのリスト @@ -167,4 +167,22 @@ { m_children.clear(); } + + @Override + public NodeID getID() + { + return null; + } + + @Override + public NodeData getData() + { + return this; + } + + @Override + public Forest getForest() + { + return null; + } } diff -r 4e0ed81bea89 -r 85061e874775 src/treecms/api/SingleNode.java --- a/src/treecms/api/SingleNode.java Tue Apr 19 19:12:16 2011 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,5 +0,0 @@ -package treecms.api; - -public interface SingleNode extends Node -{ -} diff -r 4e0ed81bea89 -r 85061e874775 src/treecms/api/Tree.java --- a/src/treecms/api/Tree.java Tue Apr 19 19:12:16 2011 +0900 +++ b/src/treecms/api/Tree.java Fri May 06 00:42:57 2011 +0900 @@ -4,11 +4,11 @@ * 木構造を表します. * @author shoshi */ -public interface Tree extends Node +public interface Tree { /** * この木構造のルートNodeを取得します. * @return ルートNode */ - Node getRoot(); + TreeNode getRoot(); } diff -r 4e0ed81bea89 -r 85061e874775 src/treecms/api/TreeNode.java --- a/src/treecms/api/TreeNode.java Tue Apr 19 19:12:16 2011 +0900 +++ b/src/treecms/api/TreeNode.java Fri May 06 00:42:57 2011 +0900 @@ -1,7 +1,25 @@ package treecms.api; -public interface TreeNode extends Node +import java.nio.ByteBuffer; +import java.util.List; +import java.util.Map; + +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 add(TreeNode _n); + public void addAll(List _list); + public void remove(TreeNode _n); + public void removeAll(List _list); + public TreeNode getParent(); - public SingleNode getNode(); + public Node getNode(); } diff -r 4e0ed81bea89 -r 85061e874775 src/treecms/memory/OnMemoryForest.java --- a/src/treecms/memory/OnMemoryForest.java Tue Apr 19 19:12:16 2011 +0900 +++ b/src/treecms/memory/OnMemoryForest.java Fri May 06 00:42:57 2011 +0900 @@ -9,7 +9,7 @@ import treecms.api.NodeData; import treecms.api.NodeID; import treecms.api.Tree; -import treecms.api.TreeEditor; +import treecms.api.MonotonicTree; import treecms.tree.id.AbstractRandomNodeID; /** @@ -99,14 +99,14 @@ * @return TreeEditor */ @Override - public TreeEditor getTreeEditor(Tree _tree) + public MonotonicTree getMonotonicTree(Tree _tree) { - Forest forest = _tree.getForest(); + Forest forest = _tree.getRoot().getNode().getForest(); if(forest != this){ throw new IllegalArgumentException(); } - return new OnMemoryTreeEditor((OnMemoryTree)_tree); + return new OnMemoryMonotonicTree((OnMemoryTree)_tree); } /** diff -r 4e0ed81bea89 -r 85061e874775 src/treecms/memory/OnMemoryMonotonicTree.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/treecms/memory/OnMemoryMonotonicTree.java Fri May 06 00:42:57 2011 +0900 @@ -0,0 +1,58 @@ +package treecms.memory; + +import treecms.api.MonotonicTree; +import treecms.api.Node; +import treecms.api.NodeData; +import treecms.tree.util.PathNotFoundException; + +public class OnMemoryMonotonicTree implements MonotonicTree +{ + public OnMemoryMonotonicTree(OnMemoryTree _tree) + { + + } + + @Override + public boolean commit(boolean _force) + { + return false; + } + + @Override + public boolean pull() + { + return false; + } + + @Override + public boolean check() + { + return false; + } + + @Override + public void merge() { + // TODO Auto-generated method stub + + } + + @Override + public Node getRoot() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Node updateTree(Node _target, NodeData _newData) + throws PathNotFoundException { + // TODO Auto-generated method stub + return null; + } + + @Override + public Node updateTree(Node _target, NodeData _newData, Node[] _path) + throws PathNotFoundException { + // TODO Auto-generated method stub + return null; + } +} diff -r 4e0ed81bea89 -r 85061e874775 src/treecms/memory/OnMemoryTree.java --- a/src/treecms/memory/OnMemoryTree.java Tue Apr 19 19:12:16 2011 +0900 +++ b/src/treecms/memory/OnMemoryTree.java Fri May 06 00:42:57 2011 +0900 @@ -11,6 +11,7 @@ import treecms.api.NodeData; import treecms.api.NodeID; import treecms.api.Tree; +import treecms.api.TreeNode; /** * オンメモリのTree実装です。 @@ -32,135 +33,13 @@ } /** - * Nodeが属するForestを取得します. - * @return Nodeが属するForest - */ - @Override - public Forest getForest() - { - return m_root.getForest(); - } - - /** - * Nodeに対応するNodeIDを取得します. - * @return Nodeに対応するNodeID - */ - @Override - public NodeID getID() - { - return m_root.getID(); - } - - /** - * Nodeが保持するデータを取得します.クライアントはこのメソッドを用いて取得されるNodeDataを用いてNodeの内容を変更できません。 - * @return Nodeが保持するNodeData - */ - @Override - public NodeData getData() - { - return m_root.getData(); - } - - /** * この木構造のルートNodeを取得します. * @return ルートNode */ @Override - public Node getRoot() - { - return m_root; - } - - /** - * 指定されたNodeを子供Nodeとして追加します. - * @param _child - */ - @Override - public void add(Node _child) - { - m_root.add(_child); - } - - /** - * 指定されたリストに含まれるNodeを,すべて子供Nodeとして追加します. - * @param _children 追加される子供Nodeを保持するリスト - */ - @Override - public void addAll(List _children) - { - m_root.addAll(_children); - } - - /** - * 子供Nodeのリストを取得します.. - * @return 子供Nodeのリスト - */ - @Override - public List children() - { - return m_root.children(); - } - - /** - * このNodeが保持する値の中で指定されたキーと対応する値を取得します. - * @param _key データに対応するキー - * @return キーと対応する値,見つからない場合はnull - */ - @Override - public ByteBuffer get(ByteBuffer _key) + public TreeNode getRoot() { - return m_root.get(_key); - } - - /** - * このNodeが保持するデータをマップとしてすべて取得します. - * @return Nodeが保持するすべてのデータのマップ - */ - @Override - public Map getAll() - { - return m_root.getAll(); - } - - /** - * キーとそれに対応する値を保存します.キーが重複した場合は上書きされます. - * @param _key キー - * @param _value 値 - */ - @Override - public void put(ByteBuffer _key,ByteBuffer _value) - { - m_root.put(_key,_value); - } - - /** - * キーとそれに対応する値を複数保持するマップを引数としてとり,マップが保持する値をすべて追加します. - * @param _map 追加される値のマップ - */ - @Override - public void putAll(Map _map) - { - m_root.putAll(_map); - } - - /** - * キーとそれに対応する値を削除します。 - * @param _key キー - */ - @Override - public void remove(ByteBuffer _key) - { - m_root.remove(_key); - } - - /** - * 子供Nodeを削除します。 - * @param _child - */ - @Override - public void remove(Node _child) - { - m_root.remove(_child); + return new OnMemoryTreeNode(m_root,null); } /** diff -r 4e0ed81bea89 -r 85061e874775 src/treecms/memory/OnMemoryTreeEditor.java --- a/src/treecms/memory/OnMemoryTreeEditor.java Tue Apr 19 19:12:16 2011 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,195 +0,0 @@ -package treecms.memory; - -import java.util.List; -import treecms.api.Forest; -import treecms.api.Node; -import treecms.api.NodeData; -import treecms.api.TreeEditor; -import treecms.merger.Merger; -import treecms.merger.ReplaceMerger; -import treecms.tree.util.NodePathFinder; -import treecms.tree.util.PathNotFoundException; - -/** - * 木構造を非破壊的に編集するオンメモリの実装です。 - * @author shoshi - */ -final class OnMemoryTreeEditor implements TreeEditor -{ - private OnMemoryTree m_tree; - private OnMemoryNode m_backup; - private OnMemoryNode m_root; - - /** - * コンストラクタです。 - * @param _tree 監視の対象とするOnMemoryTree - */ - public OnMemoryTreeEditor(OnMemoryTree _tree) - { - m_root = (OnMemoryNode)_tree.getRoot(); - m_backup = m_root; - } - - /** - * 変更を元の木構造にコミットします。この操作はコミット先が先にアップデートされていた場合は失敗します - * @param _force trueの場合は強制的に置き換えます。 - * @return コミットが成功した場合true - */ - @Override - public boolean commit(boolean _force) - { - return m_tree.compareAndSwapRootNode(m_backup,m_root,_force); - } - - /** - * 監視している木構造のルートと自身のルートに上書きします。 - * @return true - */ - @Override - public boolean pull() - { - m_root = (OnMemoryNode)m_tree.getRoot(); - m_backup = m_root; - return true; - } - - /** - * 監視している木構造が更新されていないか確認します。 - * @return 更新されている場合true、されていない場合はfalse - */ - @Override - public boolean check() - { - if(m_tree.getRoot().getID().equals(m_root.getID())){ - return false; - } - return true; - } - - /** - * 監視している木構造の内容を自分の木構造にマージします - * 最新版の木構造とマージする場合は、先にpull()を実行してください。 - */ - @Override - public void merge() - { - Merger merger = new ReplaceMerger(); - m_root = (OnMemoryNode)merger.merge(m_backup,m_root); - } - - /** - * 木構造を非破壊的に更新します. - * @param _target 更新する対象 - * @param _newData 更新に適用されるNodeData - * @param _path 対象ノードまでのパス - * @return 更新されたNode - * @throws ルートNodeから_targetまでのパスが見つからない場合、PathNotFoundException - */ - @Override - public Node updateTree(Node _target,NodeData _newData,Node[] _path) throws PathNotFoundException - { - //パスの正当性の検証 - if(_path == null){ - throw new NullPointerException("_path is null"); - } - if(_path.length == 0){ - throw new PathNotFoundException("node path is empty"); - }else{ - //ここでごちゃごちゃする - if(!m_root.getID().equals(_path[0].getID())){ - throw new PathNotFoundException("wrong root node"); - } - int size = _path.length; - Node prev = _path[0]; - //重そう - for(int i = 1;i < size;i ++){ - if(!prev.children().contains(_path[i])){ - throw new PathNotFoundException("invalid node path"); - } - } - } - - return _updateTree(_target,_newData,_path); - } - - /** - * 木構造を非破壊的に更新します. - * @param _target 更新する対象 - * @param _newData 更新に適用されるNodeData - * @return 更新されたNode - * @throws ルートNodeから_targetまでのパスが見つからない場合、PathNotFoundException - */ - @Override - public Node updateTree(Node _target,NodeData _newData) throws PathNotFoundException - { - NodePathFinder finder = new NodePathFinder(m_root,_target); - List path = finder.list(); - - return _updateTree(_target,_newData,(Node[])path.toArray()); - } - - private Node _updateTree(Node _target,NodeData _newData,Node[] _path) - { - Forest forest = m_root.getForest(); - - /* - * 改良する必要がある、ランダムアクセスの性能はデータ構造による。 - * とりあえず、配列使っとく - */ - Node ret = forest.create(_newData); - Node prev = ret; - for(int i = _path.length-1;i >= 0;i --){ - Node prevParent = _path[i]; //prevの親 - NodeData data = prevParent.getData(); - - //子供をOrderdSetにすれば早いかもね - NodeData newData = new NodeData(); - newData.putAll(data.getAll()); - for(Node child : data.children()){ - //UUIDに対応するノードを削除し、追加する - if(child.getID().isFamily(prev.getID())){ - newData.add(prev); - }else{ - newData.add(child); - } - } - - prev = forest.create(newData); - } - m_root = (OnMemoryNode)prev; - return ret; - } - - /* - private LinkedList findAndClone(OnMemoryNode _parent,OnMemoryNode _target,NodeData _newData) - { - OnMemoryForest forest = (OnMemoryForest)_target.getForest(); - if(_parent.getID().equals(_target.getID())){ - LinkedList path = new LinkedList(); - OnMemoryNode clone = forest.createNode(_target.getID().update(),_newData); - path.addFirst(clone); - return path; - } - - for(Node child : _parent.children()){ - LinkedList path = findAndClone((OnMemoryNode)child,_target,_newData); - if(path != null){ - path.addFirst(_parent); - return path; - } - } - - return null; - } - */ - - /** - * ルートNodeを取得します。 - * @return この木構造のルートNode - * */ - @Override - public Node getRoot() - { - return m_root; - } -} diff -r 4e0ed81bea89 -r 85061e874775 src/treecms/memory/OnMemoryTreeNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/treecms/memory/OnMemoryTreeNode.java Fri May 06 00:42:57 2011 +0900 @@ -0,0 +1,125 @@ +package treecms.memory; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.apache.commons.collections.list.SetUniqueList; + +import treecms.api.Forest; +import treecms.api.Node; +import treecms.api.NodeData; +import treecms.api.NodeID; +import treecms.api.SingleNode; +import treecms.api.TreeNode; + +public class OnMemoryTreeNode implements TreeNode +{ + public OnMemoryTreeNode m_parent; + public OnMemoryNode m_node; + + public OnMemoryTreeNode(OnMemoryNode _node,OnMemoryTreeNode _parent) + { + if(_node == null){ + throw new NullPointerException(); + } + + m_node = _node; + + //このノードがルートの場合、親はnullで構わない. + m_parent = _parent; + } + + @Override + public NodeID getID() + { + return m_node.getID(); + } + + @Override + public NodeData getData() + { + return m_node.getData(); + } + + @Override + public Forest getForest() + { + return m_node.getForest(); + } + + @Override + public List children() + { + /* + * 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)); + } + + return ret; + } + + @Override + public Map getAll() + { + return m_node.getAll(); + } + + @Override + public ByteBuffer get(ByteBuffer _key) + { + return m_node.get(_key); + } + + @Override + public void addAll(List _children) + { + } + + @Override + public void add(Node _child) { + // TODO Auto-generated method stub + + } + + @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 + + } + + @Override + public TreeNode getParent() { + // TODO Auto-generated method stub + return null; + } + + @Override + public SingleNode getNode() { + // TODO Auto-generated method stub + return null; + } + +} diff -r 4e0ed81bea89 -r 85061e874775 src/treecms/test/GenericsTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/treecms/test/GenericsTest.java Fri May 06 00:42:57 2011 +0900 @@ -0,0 +1,32 @@ +package treecms.test; + +import java.util.ArrayList; +import java.util.List; + +public class GenericsTest +{ + public static void main(String _args[]) + { + GenericsTest h = new GenericsTest(null); + } + + public GenericsTest(E _instance) + { + E kasu = (E)_instance.get(); + } +} + +interface Foo +{ + public Foo get(); + public List list(); +} + +interface Hoge extends Foo +{ + @Override + public Hoge get(); + + @Override + public List list(); +} \ No newline at end of file diff -r 4e0ed81bea89 -r 85061e874775 src/treecms/tree/cassandra/v1/util/CassandraClientWrapper.java --- a/src/treecms/tree/cassandra/v1/util/CassandraClientWrapper.java Tue Apr 19 19:12:16 2011 +0900 +++ b/src/treecms/tree/cassandra/v1/util/CassandraClientWrapper.java Fri May 06 00:42:57 2011 +0900 @@ -162,6 +162,27 @@ } /** + * describe_cluster_name の ラッパーメソッド + * @return cluster name + * @throws TException + */ + public String describe_cluster_name() throws TException + { + for(int i = 0;i < m_retryCount;i ++){ + if(m_client == null){ + throw new IllegalStateException("Cassandra.Client is disconnected. "+m_host+":"+m_port); + } + + try { + return m_client.describe_cluster_name(); + }catch(Exception _e){ + exceptionHandler(_e); + } + } + return m_client.describe_cluster_name(); + } + + /** * Cassandra.Client.insertのラッパーメソッド */ public void insert(String _ks,String _key,ColumnPath _path,byte[] _value,long _timestamp,ConsistencyLevel _level) throws InvalidRequestException, UnavailableException, TimedOutException, TException diff -r 4e0ed81bea89 -r 85061e874775 src/treecms/tree/cassandra/v1/util/ConcurrentCassandraClient.java --- a/src/treecms/tree/cassandra/v1/util/ConcurrentCassandraClient.java Tue Apr 19 19:12:16 2011 +0900 +++ b/src/treecms/tree/cassandra/v1/util/ConcurrentCassandraClient.java Fri May 06 00:42:57 2011 +0900 @@ -1,14 +1,19 @@ package treecms.tree.cassandra.v1.util; import java.util.concurrent.Callable; +import java.util.List; +import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import org.apache.cassandra.thrift.ColumnOrSuperColumn; +import org.apache.cassandra.thrift.ColumnParent; import org.apache.cassandra.thrift.ColumnPath; import org.apache.cassandra.thrift.ConsistencyLevel; +import org.apache.cassandra.thrift.Mutation; +import org.apache.cassandra.thrift.SlicePredicate; /** * @@ -55,6 +60,38 @@ return ret; } + public Future> get_slice(final String _ks,final String _key,final ColumnParent _parent,final SlicePredicate _predicate,final ConsistencyLevel _level) + { + Callable> task = new Callable>(){ + @Override + public List call() throws Exception + { + CassandraClientWrapper client = ((CassandraClientThread)Thread.currentThread()).getClientWrapper(); + List ret = client.get_slice(_ks,_key,_parent,_predicate,_level); + return ret; + } + }; + + Future> ret = m_service.submit(task); + return ret; + } + + public Future batch_mutate(final String _ks,final Map>> _mutation_map,final ConsistencyLevel _level) + { + Callable task = new Callable(){ + @Override + public Boolean call() throws Exception + { + CassandraClientWrapper client = ((CassandraClientThread)Thread.currentThread()).getClientWrapper(); + client.batch_mutate(_ks,_mutation_map,_level); + return true; + } + }; + + Future ret = m_service.submit(task); + return ret; + } + public Future insert(final String _ks,final String _key,final ColumnPath _path,final byte[] _value,final long _timestamp,final ConsistencyLevel _level) { Callable task = new Callable(){ @@ -70,4 +107,18 @@ Future ret = m_service.submit(task); return ret; } + + public Future describe_cluster_name() + { + Callable task = new Callable(){ + @Override + public String call() throws Exception + { + return null; + } + }; + + Future ret = m_service.submit(task); + return ret; + } }