Mercurial > hg > Members > shoshi > TreeCMSv2
changeset 8:f96193babac0
changed byte[] to ByteBuffer
added TreeEditor.updateTree(Node,NodeData,Node[]) for node path is known.
added GUIEditor
author | shoshi |
---|---|
date | Thu, 31 Mar 2011 02:08:44 +0900 |
parents | fc19e38b669b |
children | 17ed97ca9960 |
files | CHANGELOG src/treecms/api/Forest.java src/treecms/api/Node.java src/treecms/api/NodeData.java src/treecms/api/TreeEditor.java src/treecms/gui/AddChildDialog.java src/treecms/gui/AttributeEditorTable.java src/treecms/gui/GUIEditor.java src/treecms/gui/NodeViewerTree.java src/treecms/memory/OnMemoryForest.java src/treecms/memory/OnMemoryNode.java src/treecms/memory/OnMemoryTree.java src/treecms/memory/OnMemoryTreeEditor.java src/treecms/test/ByteArrayTest.java src/treecms/tree/cassandra/v1/CassandraForest.java src/treecms/tree/util/PathNotFoundException.java |
diffstat | 16 files changed, 693 insertions(+), 25 deletions(-) [+] |
line wrap: on
line diff
--- a/CHANGELOG Thu Mar 17 23:24:08 2011 +0900 +++ b/CHANGELOG Thu Mar 31 02:08:44 2011 +0900 @@ -1,5 +1,8 @@ ChangeLog. - +2011-03-29 + changed byte[] to ByteBuffer + added TreeEditor.updateTree(Node,NodeData,Node[]) for node path is known. + added GUIEditor 2011-03-17 added concurrent access client for cassandra 2011-03-14
--- a/src/treecms/api/Forest.java Thu Mar 17 23:24:08 2011 +0900 +++ b/src/treecms/api/Forest.java Thu Mar 31 02:08:44 2011 +0900 @@ -14,6 +14,20 @@ Node get(NodeID _id); /** + * あるNodeをルートとしてTreeのオブジェクトを取得します。 + * @param _id 木のルートとなるNodeのNodeID + * @return Tree + */ + Tree getAsTree(NodeID _id); + + /** + * あるNodeをルートとしたTreeを非破壊的に編集するTreeEditorを取得します。 + * @param _id 木のルートとなるNodeのNodeID + * @return TreeEditor + */ + TreeEditor getAsTreeEditor(NodeID _id); + + /** * 同じUUIDを持つNode中で最新のNodeを取得します. * @param _uuid NodeIDのUUID * @return UUIDと一致するNodeが見つからない場合はnullを返します. @@ -33,4 +47,10 @@ * @return NodeDataを保持した新しいNode */ Node create(NodeData _data); + + /** + * このForestの現在の最新のMainTreeを取得します + * @return このForestのMainTree、最新版 + */ + Tree getMainTree(); }
--- a/src/treecms/api/Node.java Thu Mar 17 23:24:08 2011 +0900 +++ b/src/treecms/api/Node.java Thu Mar 31 02:08:44 2011 +0900 @@ -2,6 +2,7 @@ import java.util.List; import java.util.Map; +import java.nio.ByteBuffer; /** * 木構造の基本のデータ単位であるNodeを示します.Nodeは子供のリストとデータのマップを保持します.また,クライアントはノードが保持しているデータをNodeDataとして @@ -38,14 +39,14 @@ * このNodeが保持するデータをマップとしてすべて取得します. * @return Nodeが保持するすべてのデータのマップ */ - public Map<byte[],byte[]> getAll(); + public Map<ByteBuffer,ByteBuffer> getAll(); /** * このNodeが保持する値の中で指定されたキーと対応する値を取得します. * @param _key データに対応するキー * @return キーと対応する値,見つからない場合はnull */ - public byte[] get(byte[] _key); + public ByteBuffer get(ByteBuffer _key); /** * 指定されたリストに含まれるNodeを,すべて子供Nodeとして追加します. @@ -60,15 +61,27 @@ public void add(Node _child); /** + * 指定されたNodeを削除します。 + * @param _child + */ + public void remove(Node _child); + + /** * キーとそれに対応する値を保存します.キーが重複した場合は上書きされます. * @param _key キー * @param _value 値 */ - public void put(byte[] _key,byte[] _value); + public void put(ByteBuffer _key,ByteBuffer _value); + + /** + * キーとそれに対応する値を削除します。 + * @param _key キー + */ + public void remove(ByteBuffer _key); /** * キーとそれに対応する値を複数保持するマップを引数としてとり,マップが保持する値をすべて追加します. * @param _map 追加される値のマップ */ - public void putAll(Map<byte[],byte[]> _map); + public void putAll(Map<ByteBuffer,ByteBuffer> _map); } \ No newline at end of file
--- a/src/treecms/api/NodeData.java Thu Mar 17 23:24:08 2011 +0900 +++ b/src/treecms/api/NodeData.java Thu Mar 31 02:08:44 2011 +0900 @@ -1,5 +1,6 @@ package treecms.api; +import java.nio.ByteBuffer; import java.util.Collections; import java.util.List; import java.util.Map; @@ -23,7 +24,7 @@ /** * キーと対応する値のマップ */ - private Map<byte[],byte[]> m_attrs; + private Map<ByteBuffer,ByteBuffer> m_attrs; /** * コンストラクタです.なにもしません @@ -41,11 +42,11 @@ { if(_data != null){ m_children = new CopyOnWriteArrayList<Node>(_data.m_children); - m_attrs = new ConcurrentHashMap<byte[],byte[]>(_data.m_attrs); + m_attrs = new ConcurrentHashMap<ByteBuffer,ByteBuffer>(_data.m_attrs); return; } m_children = new CopyOnWriteArrayList<Node>(); - m_attrs = new ConcurrentHashMap<byte[],byte[]>(); + m_attrs = new ConcurrentHashMap<ByteBuffer,ByteBuffer>(); } /** @@ -61,7 +62,7 @@ * キーのセットを取得します. * @return キーのセット */ - public Set<byte[]> keySet() + public Set<ByteBuffer> keySet() { return m_attrs.keySet(); } @@ -71,7 +72,7 @@ * @param _name * @return キーに対応する値 */ - public byte[] get(byte[] _name) + public ByteBuffer get(ByteBuffer _name) { return m_attrs.get(_name); } @@ -81,16 +82,25 @@ * @param _name キー * @param _value 値 */ - public void put(byte[] _name,byte[] _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<byte[],byte[]> _map) + public void putAll(Map<ByteBuffer,ByteBuffer> _map) { m_attrs.putAll(_map); } @@ -145,7 +155,7 @@ * NodeDataが保持しているすべてのキーと値の組のマップを返します. * @return すべてのキーと値のマップ */ - public Map<byte[],byte[]> getAll() + public Map<ByteBuffer,ByteBuffer> getAll() { return Collections.unmodifiableMap(m_attrs); }
--- a/src/treecms/api/TreeEditor.java Thu Mar 17 23:24:08 2011 +0900 +++ b/src/treecms/api/TreeEditor.java Thu Mar 31 02:08:44 2011 +0900 @@ -49,4 +49,15 @@ * @throws PathNotFoundException パスが見つからない場合 */ public Node updateTree(Node _target,NodeData _newData) throws PathNotFoundException; + + /** + * 木構造を非破壊的に更新します.Nodeへのパスが既知な場合このメソッドを使用できます。 + * このメソッドは使用時にパスの正当性を検証します。見つからない場合PathNotFoundExceptionがスローされます + * @param _target + * @param _newData + * @param _path + * @return 更新された新しいNode + * @throws PathNotFoundException + */ + public Node updateTree(Node _target,NodeData _newData,Node[] _path) throws PathNotFoundException; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/treecms/gui/AddChildDialog.java Thu Mar 31 02:08:44 2011 +0900 @@ -0,0 +1,63 @@ +package treecms.gui; + +import java.awt.BorderLayout; +import java.awt.Container; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.nio.ByteBuffer; +import java.util.Map; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JScrollPane; + +class AddChildDialog +{ + private JDialog m_dialog; + private AttributeEditorTable m_table; + private JButton m_submit; + private Map<ByteBuffer,ByteBuffer> m_data; + private JFrame m_parent; + + public AddChildDialog(JFrame _parent,boolean _modal) + { + m_dialog = new JDialog(_parent,_modal); + m_dialog.setSize(300,200); + m_dialog.setTitle("Add new child"); + m_parent = _parent; + m_table = new AttributeEditorTable(); + m_submit = new JButton("submit"); + m_submit.addActionListener(new ActionListener(){ + @Override + public void actionPerformed(ActionEvent _e) + { + m_data = m_table.getAttributeMap(); + m_dialog.setVisible(false); + } + }); + m_dialog.addWindowListener(new WindowAdapter(){ + @Override + public void windowClosing(WindowEvent _e) + { + m_data = null; + } + }); + + Container cnt = m_dialog.getContentPane(); + cnt.setLayout(new BorderLayout()); + cnt.add(new JLabel("Attributes"),BorderLayout.NORTH); + cnt.add(new JScrollPane(m_table),BorderLayout.CENTER); + cnt.add(m_submit,BorderLayout.SOUTH); + } + + public Map<ByteBuffer,ByteBuffer> setVisible(boolean _show) + { + m_dialog.setLocationRelativeTo(m_parent); + m_dialog.setVisible(_show); + + return m_data; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/treecms/gui/AttributeEditorTable.java Thu Mar 31 02:08:44 2011 +0900 @@ -0,0 +1,99 @@ +package treecms.gui; + +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.Map; + +import javax.swing.JTable; +import javax.swing.table.DefaultTableModel; + +class AttributeEditorTable extends JTable +{ + private static final long serialVersionUID = -3520371233895896649L; + private static final String ADD_ROW_STR = "add new attribute..."; + private static final Object ADD_ROW = new Object(){ + @Override + public String toString() + { + return ADD_ROW_STR; + } + }; + + private static final String[] COLUMNS = new String[]{"Key","Value"}; + private static final String[] DEFAULT_VALUES = new String[]{"new key","new value"}; + + public AttributeEditorTable() + { + super(new AETableModel()); + + addMouseListener(new MouseAdapter(){ + @Override + public void mouseClicked(MouseEvent _e) + { + if(_e.getClickCount() == 2){ + int row = getSelectedRow(); + Object val = getValueAt(row,0); + if(val == ADD_ROW){ + DefaultTableModel model = (DefaultTableModel)AttributeEditorTable.this.getModel(); + model.insertRow(row,DEFAULT_VALUES); + } + } + } + }); + } + + public void setAttributeMap(Map<ByteBuffer,ByteBuffer> _map) + { + AETableModel model = (AETableModel)getModel(); + model.clear(); + for(ByteBuffer _key : _map.keySet()){ + model.insertRow(0,new String[]{new String(_key.array()),new String(_map.get(_key).array())}); + } + } + + public Map<ByteBuffer,ByteBuffer> getAttributeMap() + { + Map<ByteBuffer,ByteBuffer> map = new HashMap<ByteBuffer,ByteBuffer>(); + for(int i = 0;true;i ++){ + Object key = getValueAt(i,0); + Object value = getValueAt(i,1); + + if(key == ADD_ROW){ + break; + } + + ByteBuffer bufKey = ByteBuffer.wrap(key.toString().getBytes()); + ByteBuffer bufValue = ByteBuffer.wrap(value.toString().getBytes()); + map.put(bufKey,bufValue); + } + + return map; + } + + private static class AETableModel extends DefaultTableModel + { + private static final long serialVersionUID = -5641721228388548196L; + + public AETableModel() + { + super(); + setColumnIdentifiers(COLUMNS); + addRow(new Object[]{ADD_ROW,""}); + } + + public void clear() + { + setRowCount(0); + addRow(new Object[]{ADD_ROW,""}); + } + + @Override + public boolean isCellEditable(int _row,int _col) + { + Object val = this.getValueAt(_row,_col); + return (val == ADD_ROW) ? false : true; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/treecms/gui/GUIEditor.java Thu Mar 31 02:08:44 2011 +0900 @@ -0,0 +1,249 @@ +package treecms.gui; + +import java.awt.BorderLayout; +import java.awt.Container; +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.nio.ByteBuffer; +import java.util.Map; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import javax.swing.JScrollPane; +import javax.swing.JSplitPane; +import javax.swing.JTree; +import javax.swing.SwingUtilities; +import javax.swing.border.TitledBorder; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; + +import treecms.api.Node; +import treecms.api.NodeData; +import treecms.api.Tree; +import treecms.api.TreeEditor; +import treecms.memory.OnMemoryForest; + +public class GUIEditor +{ + private static final String TITLE = "GUIEditor"; + + //GUIコンポーネント + private JFrame m_frame; + private JTree m_nodeTree; + private AttributeEditorTable m_attrTable; + private JButton m_commit,m_pull,m_check,m_merge; + private JButton m_attrSave,m_attrCancel; + private JPopupMenu m_popup; + private JMenuItem m_addChild,m_removeChild; + + //TreeEditor + private TreeEditor m_editor; + + //イベントハンドラ + private ActionListener m_actionListener; + private MouseListener m_mouseListener; + private TreeSelectionListener m_treeSelectionListener; + + public static void main(String _args[]) + { + OnMemoryForest forest = new OnMemoryForest(); + Tree root = forest.getMainTree(); + TreeEditor editor = forest.getAsTreeEditor(root.getID()); + new GUIEditor(editor); + } + + public GUIEditor(TreeEditor _editor) + { + m_editor = _editor; + m_frame = new JFrame(TITLE+":"+m_editor.toString()); + m_frame.setSize(500,500); + + m_actionListener = new EditorActionListener(); + m_mouseListener = new EditorMouseListener(); + m_treeSelectionListener = new EditorTreeSelectionListener(); + + Container pane = m_frame.getContentPane(); + pane.setLayout(new BorderLayout()); + + JPanel treePanel = initNodeTree(); + JPanel menuPanel = initMenuButtons(); + JPanel attrPanel = initAttributeTable(); + + JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,treePanel,attrPanel); + + pane.add(menuPanel,BorderLayout.NORTH); + pane.add(splitPane,BorderLayout.CENTER); + m_frame.setVisible(true); + splitPane.setDividerLocation(0.5); + m_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + } + + private JPanel initMenuButtons() + { + JPanel panel = new JPanel(); + m_commit = new JButton("commit"); + m_pull = new JButton("pull"); + m_check = new JButton("check"); + m_merge = new JButton("merge"); + + panel.setBorder(new TitledBorder("Editor Menu")); + panel.setLayout(new GridLayout(1,4)); + panel.add(m_commit); + panel.add(m_pull); + panel.add(m_check); + panel.add(m_merge); + + return panel; + } + + private JPanel initAttributeTable() + { + JPanel panel = new JPanel(); + m_attrTable = new AttributeEditorTable(); + m_attrSave = new JButton("save"); + m_attrSave.addActionListener(m_actionListener); + m_attrCancel = new JButton("cancel"); + m_attrCancel.addActionListener(m_actionListener); + + JPanel btnPanel = new JPanel(); + btnPanel.setLayout(new GridLayout(1,2)); + btnPanel.add(m_attrSave); + btnPanel.add(m_attrCancel); + + panel.setBorder(new TitledBorder("Attributes")); + panel.setLayout(new BorderLayout()); + panel.add(new JScrollPane(m_attrTable),BorderLayout.CENTER); + panel.add(btnPanel,BorderLayout.SOUTH); + + return panel; + } + + private JPanel initNodeTree() + { + JPanel panel = new JPanel(); + m_nodeTree = new NodeViewerTree(m_editor.getRoot()); + m_nodeTree.addTreeSelectionListener(m_treeSelectionListener); + + m_popup = new JPopupMenu(); + m_addChild = new JMenuItem("Add Child"); + m_removeChild = new JMenuItem("Remove Child"); + m_popup.add(m_addChild); + m_popup.add(m_removeChild); + m_addChild.addActionListener(m_actionListener); + m_removeChild.addActionListener(m_actionListener); + m_nodeTree.addMouseListener(m_mouseListener); + + panel.setBorder(new TitledBorder("Tree Viewer")); + panel.setLayout(new BorderLayout()); + panel.add(new JScrollPane(m_nodeTree),BorderLayout.CENTER); + + return panel; + } + + private class EditorActionListener implements ActionListener + { + @Override + public void actionPerformed(ActionEvent _e) + { + Object source = _e.getSource(); + if(source == m_addChild){ + //新しいノードを追加する + AddChildDialog addDialog = new AddChildDialog(GUIEditor.this.m_frame,true); + Map<ByteBuffer,ByteBuffer> result = addDialog.setVisible(true); + if(result != null){ + //キャンセルされなかった場合 + NodeData data = new NodeData(); + data.putAll(result); + + DefaultMutableTreeNode node = (DefaultMutableTreeNode)m_nodeTree.getLastSelectedPathComponent(); + + Node parent = (Node)node.getUserObject(); + Node child = parent.getForest().create(data); + parent.add(child); + + DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(child); + node.add(newNode); + + DefaultTreeModel model = (DefaultTreeModel)m_nodeTree.getModel(); + model.reload(); + } + } + + if(source == m_removeChild){ + //ノードを削除する + DefaultMutableTreeNode guiNode = (DefaultMutableTreeNode)m_nodeTree.getLastSelectedPathComponent(); + DefaultMutableTreeNode guiParent = (DefaultMutableTreeNode)guiNode.getParent(); + if(guiParent == null){ + JOptionPane.showMessageDialog(m_frame,"RootNodeは削除できません"); + return; + } + + guiParent.remove(guiNode); + + Node treeNode = (Node)guiNode.getUserObject(); + Node treeParent = (Node)guiNode.getUserObject(); + treeParent.remove(treeNode); + + DefaultTreeModel model = (DefaultTreeModel)m_nodeTree.getModel(); + model.reload(); + } + + if(source == m_attrSave){ + //ノードの変更を保存する + DefaultMutableTreeNode guiNode = (DefaultMutableTreeNode)m_nodeTree.getLastSelectedPathComponent(); + if(guiNode == null){ + //ノードが選択されずに編集された + JOptionPane.showMessageDialog(m_frame,"編集対象のノードが選択されていません。"); + return; + } + + Node treeNode = (Node)guiNode.getUserObject(); + Map<ByteBuffer,ByteBuffer> attrMap = m_attrTable.getAttributeMap(); + treeNode.putAll(attrMap); + } + + if(source == m_attrCancel){ + //ノードへの編集を捨てる + DefaultMutableTreeNode guiNode = (DefaultMutableTreeNode)m_nodeTree.getLastSelectedPathComponent(); + Node treeNode = (Node)guiNode.getUserObject(); + m_attrTable.setAttributeMap(treeNode.getAll()); + } + } + } + + private class EditorTreeSelectionListener implements TreeSelectionListener + { + @Override + public void valueChanged(TreeSelectionEvent _e) + { + DefaultMutableTreeNode guiNode = (DefaultMutableTreeNode)m_nodeTree.getLastSelectedPathComponent(); + if(guiNode == null){ + return; + } + + Node treeNode = (Node)guiNode.getUserObject(); + m_attrTable.setAttributeMap(treeNode.getAll()); + } + } + + private class EditorMouseListener extends MouseAdapter + { + @Override + public void mouseClicked(MouseEvent _e) + { + if(SwingUtilities.isRightMouseButton(_e) && !m_nodeTree.isSelectionEmpty()){ + //ポップアップメニューを表示する + m_popup.show(m_nodeTree,_e.getX(),_e.getY()); + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/treecms/gui/NodeViewerTree.java Thu Mar 31 02:08:44 2011 +0900 @@ -0,0 +1,65 @@ +package treecms.gui; + +import javax.swing.JTree; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; + +import treecms.api.Node; +import treecms.api.TreeEditor; + +public class NodeViewerTree extends JTree +{ + private static final long serialVersionUID = 8257838201307216301L; + + public NodeViewerTree(Node _node) + { + super(new NVTreeModel(_node)); + } + + public void addChildToSelectedNode(Node _child) + { + DefaultMutableTreeNode node = (DefaultMutableTreeNode)this.getLastSelectedPathComponent(); + if(node == null){ + return; + } + + DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(); + newNode.setUserObject(_child); + node.add(newNode); + } + + private static class NVTreeModel extends DefaultTreeModel + { + public NVTreeModel(Node _node) + { + super(new DefaultMutableTreeNode()); + setTree(_node,false); + } + + public void setTree(Node _node,boolean _reload) + { + DefaultMutableTreeNode root = (DefaultMutableTreeNode)getRoot(); + root.removeAllChildren(); + root.setUserObject(_node); + + for(Node child : _node.children()){ + treewalk(child,root); + } + + if(_reload){ + reload(); + } + } + + private void treewalk(Node _node,DefaultMutableTreeNode _treeNode) + { + DefaultMutableTreeNode treeChild = new DefaultMutableTreeNode(); + treeChild.setUserObject(_node); + _treeNode.add(treeChild); + + for(Node child : _node.children()){ + treewalk(child,treeChild); + } + } + } +}
--- a/src/treecms/memory/OnMemoryForest.java Thu Mar 17 23:24:08 2011 +0900 +++ b/src/treecms/memory/OnMemoryForest.java Thu Mar 31 02:08:44 2011 +0900 @@ -8,6 +8,8 @@ import treecms.api.Node; import treecms.api.NodeData; import treecms.api.NodeID; +import treecms.api.Tree; +import treecms.api.TreeEditor; import treecms.tree.id.AbstractRandomNodeID; /** @@ -22,6 +24,9 @@ //最新版Nodeのマップ Map<String,OnMemoryNode> m_tipTable; + //MainTreeのUUID + String m_mainID; + /** * コンストラクタ */ @@ -29,6 +34,8 @@ { m_table = new ConcurrentHashMap<NodeID,OnMemoryNode>(); m_tipTable = new ConcurrentHashMap<String,OnMemoryNode>(); + + m_mainID = createNode(null,null).getID().getUUID(); } /** @@ -37,7 +44,7 @@ * @param _newData Nodeが保持するNodeData * @return 作成されたOnMemoryNode */ - OnMemoryNode createNode(NodeID _id,NodeData _newData) + public OnMemoryNode createNode(NodeID _id,NodeData _newData) { NodeID newID = (_id != null) ? _id : createID(); NodeData newData = (_newData != null) ? _newData : new NodeData(); @@ -72,6 +79,28 @@ } /** + * あるNodeをルートとしてTreeのオブジェクトを取得します。 + * @param _id 木のルートとなるNodeのNodeID + * @return Tree + */ + @Override + public Tree getAsTree(NodeID _id) + { + return new OnMemoryTree((OnMemoryNode) get(_id)); + } + + /** + * あるNodeをルートとしたTreeを非破壊的に編集するTreeEditorを取得します。 + * @param _id 木のルートとなるNodeのNodeID + * @return TreeEditor + */ + @Override + public TreeEditor getAsTreeEditor(NodeID _id) + { + return new OnMemoryTreeEditor((OnMemoryTree) getAsTree(_id)); + } + + /** * 新しくNodeを作成します. * @return 新しいNode */ @@ -100,6 +129,16 @@ { return m_tipTable.get(_uuid); } + + /** + * MainTreeを取得します。 + * @return このForestのMainTree + */ + @Override + public Tree getMainTree() + { + return new OnMemoryTree(m_tipTable.get(m_mainID)); + } /** * ランダムにバージョン番号を生成するNodeIDです.ファクトリを内包します.
--- a/src/treecms/memory/OnMemoryNode.java Thu Mar 17 23:24:08 2011 +0900 +++ b/src/treecms/memory/OnMemoryNode.java Thu Mar 31 02:08:44 2011 +0900 @@ -1,5 +1,6 @@ package treecms.memory; +import java.nio.ByteBuffer; import java.util.List; import java.util.Map; import treecms.api.Forest; @@ -70,6 +71,16 @@ { m_data.add(_child); } + + /** + * 子供Nodeを削除します。 + * @param _child + */ + @Override + public void remove(Node _child) + { + m_data.remove(_child); + } /** * 指定されたリストに含まれるNodeを,すべて子供Nodeとして追加します. @@ -97,7 +108,7 @@ * @return キーと対応する値,見つからない場合はnull */ @Override - public byte[] get(byte[] _key) + public ByteBuffer get(ByteBuffer _key) { return m_data.get(_key); } @@ -107,7 +118,7 @@ * @return Nodeが保持するすべてのデータのマップ */ @Override - public Map<byte[],byte[]> getAll() + public Map<ByteBuffer,ByteBuffer> getAll() { return m_data.getAll(); } @@ -118,7 +129,7 @@ * @param _value 値 */ @Override - public void put(byte[] _key, byte[] _value) + public void put(ByteBuffer _key, ByteBuffer _value) { m_data.put(_key,_value); } @@ -128,8 +139,24 @@ * @param _map 追加される値のマップ */ @Override - public void putAll(Map<byte[], byte[]> _map) + public void putAll(Map<ByteBuffer, ByteBuffer> _map) { m_data.putAll(_map); } + + /** + * キーとそれに対応する値を削除します。 + * @param _key キー + */ + @Override + public void remove(ByteBuffer _key) + { + m_data.remove(_key); + } + + @Override + public String toString() + { + return getID().toString(); + } }
--- a/src/treecms/memory/OnMemoryTree.java Thu Mar 17 23:24:08 2011 +0900 +++ b/src/treecms/memory/OnMemoryTree.java Thu Mar 31 02:08:44 2011 +0900 @@ -1,5 +1,6 @@ package treecms.memory; +import java.nio.ByteBuffer; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; @@ -17,7 +18,6 @@ */ final class OnMemoryTree implements Tree { - private OnMemoryNode m_root; private AtomicReference<OnMemoryNode> m_ref; /** @@ -26,7 +26,6 @@ */ public OnMemoryTree(OnMemoryNode _newRoot) { - m_root = _newRoot; m_ref = new AtomicReference<OnMemoryNode>(_newRoot); } @@ -106,7 +105,7 @@ * @return キーと対応する値,見つからない場合はnull */ @Override - public byte[] get(byte[] _key) + public ByteBuffer get(ByteBuffer _key) { return m_ref.get().get(_key); } @@ -116,7 +115,7 @@ * @return Nodeが保持するすべてのデータのマップ */ @Override - public Map<byte[],byte[]> getAll() + public Map<ByteBuffer,ByteBuffer> getAll() { return m_ref.get().getAll(); } @@ -127,7 +126,7 @@ * @param _value 値 */ @Override - public void put(byte[] _key,byte[] _value) + public void put(ByteBuffer _key,ByteBuffer _value) { m_ref.get().put(_key,_value); } @@ -137,12 +136,32 @@ * @param _map 追加される値のマップ */ @Override - public void putAll(Map<byte[], byte[]> _map) + public void putAll(Map<ByteBuffer, ByteBuffer> _map) { m_ref.get().putAll(_map); } /** + * キーとそれに対応する値を削除します。 + * @param _key キー + */ + @Override + public void remove(ByteBuffer _key) + { + m_ref.get().remove(_key); + } + + /** + * 子供Nodeを削除します。 + * @param _child + */ + @Override + public void remove(Node _child) + { + m_ref.get().remove(_child); + } + + /** * ルートNodeを比較して置き換えます. * @param _except 比較する対象 * @param _newRoot 一致した場合置き換える対象 @@ -156,4 +175,5 @@ m_ref.set(_newRoot); return true; } + }
--- a/src/treecms/memory/OnMemoryTreeEditor.java Thu Mar 17 23:24:08 2011 +0900 +++ b/src/treecms/memory/OnMemoryTreeEditor.java Thu Mar 31 02:08:44 2011 +0900 @@ -1,7 +1,6 @@ package treecms.memory; import java.util.LinkedList; - import treecms.api.Node; import treecms.api.NodeData; import treecms.api.NodeID; @@ -79,6 +78,27 @@ } /** + * 実装しろ + */ + @Override + public synchronized Node updateTree(Node _target,NodeData _newData,Node[] _path) throws PathNotFoundException + { + //パスの正当性の検証 + if(_path.length == 0){ + throw new PathNotFoundException("node path is empty"); + }else{ + //ここでごちゃごちゃする + //めんどくさい + } + + + + + + return null; + } + + /** * 木構造を非破壊的に更新します. * @param _target 更新する対象 * @param _newData 更新に適用されるNodeData
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/treecms/test/ByteArrayTest.java Thu Mar 31 02:08:44 2011 +0900 @@ -0,0 +1,15 @@ +package treecms.test; + +import java.util.*; + +public class ByteArrayTest +{ + public static void main(String _args[]) + { + byte key1[] = new byte[]{12,23,23,43}; + byte key2[] = new byte[]{12,23,23,43}; + + System.out.println(key1.equals(key2)); + + } +}
--- a/src/treecms/tree/cassandra/v1/CassandraForest.java Thu Mar 17 23:24:08 2011 +0900 +++ b/src/treecms/tree/cassandra/v1/CassandraForest.java Thu Mar 31 02:08:44 2011 +0900 @@ -79,9 +79,14 @@ public CassandraForest(String _host,int _port,String _ks,int _threads) { m_service = Executors.newFixedThreadPool(_threads,new ClientThreadFactory(_host,_port)); + m_cache = new ConcurrentHashMap<NodeID,CassandraNode>(); m_tipCache = new ConcurrentHashMap<String,CassandraNode>(); } + + private void loadContents() + { + } @Override public Node get(NodeID _id)
--- a/src/treecms/tree/util/PathNotFoundException.java Thu Mar 17 23:24:08 2011 +0900 +++ b/src/treecms/tree/util/PathNotFoundException.java Thu Mar 31 02:08:44 2011 +0900 @@ -19,4 +19,13 @@ { super("Path Not Found from "+_from.getID()+" to "+_to.getID()); } + + /** + * コンストラクタです。 + * @param _message メッセージ + */ + public PathNotFoundException(String _message) + { + super(_message); + } }