# HG changeset patch # User suika6039 # Date 1296237920 -32400 # Node ID 5b36891db5ca4f0a8484f1ebd03d3622cf6d69b0 # Parent a529aad2ac92d0458c4a14c2087150550aa434e2 finished implementing cassandra monotonic tree diff -r a529aad2ac92 -r 5b36891db5ca src/treecms/proto/cassandra/CassBrowser.java --- a/src/treecms/proto/cassandra/CassBrowser.java Sat Jan 22 22:55:19 2011 +0900 +++ b/src/treecms/proto/cassandra/CassBrowser.java Sat Jan 29 03:05:20 2011 +0900 @@ -1,11 +1,18 @@ package treecms.proto.cassandra; +import java.nio.CharBuffer; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.StringTokenizer; + import treecms.proto.api.Browser; import treecms.proto.api.Node; import treecms.proto.api.NodeID; -import org.apache.thrift.TException; import org.apache.thrift.transport.TTransport; import org.apache.thrift.transport.TFramedTransport; import org.apache.thrift.transport.TSocket; @@ -17,23 +24,26 @@ import org.apache.cassandra.thrift.ColumnParent; import org.apache.cassandra.thrift.ColumnPath; import org.apache.cassandra.thrift.ConsistencyLevel; -import org.apache.cassandra.thrift.InvalidRequestException; import org.apache.cassandra.thrift.KeySlice; import org.apache.cassandra.thrift.SlicePredicate; import org.apache.cassandra.thrift.SliceRange; -import org.apache.cassandra.thrift.TimedOutException; -import org.apache.cassandra.thrift.UnavailableException; public class CassBrowser implements Browser { - public static void main(String _args[])throws Exception - { - } - private Cassandra.Client m_cassandra; private String m_host,m_port; private String m_keySpace,m_colFamily; + private static final String TREEINFO = "TreeInfo"; + private static final String ROOTNODE = "RootNode"; + + private static final String CLASSNAME = "ClassName"; + private static final String TITLE = "title"; + private static final String CHILDREN = "Children"; + private static final String CHILDREN_DELIM = ","; + + private static final String ATTR_PREFIX = "_"; + private CassBrowser(String _host,String _port) throws TTransportException { m_host = _host; @@ -69,9 +79,270 @@ return browser; } - public String getColumn(NodeID _id,String _colName) + public Node addChild(NodeID _id,Node _child) + { + LinkedList tmp = new LinkedList(); + tmp.add(_child); + addChildren(_id,tmp); + return _child; + } + + public void addChildren(NodeID _id,List _children) + { + String children = getChildrenRaw(_id); + Map set = new HashMap(); + StringTokenizer st = new StringTokenizer(children,CHILDREN_DELIM); + while(st.hasMoreElements()){ + set.put(st.nextToken(),Boolean.TRUE); + } + + StringBuffer buf = new StringBuffer(); + + if(!set.isEmpty()){ + buf.append(CHILDREN_DELIM); + } + + for(int i = 0;i < _children.size() - 1;i ++){ + String key = _children.get(i).getID().toString(); + if(set.get(key) != null){ + return; + } + + buf.append(key).append(CHILDREN_DELIM); + } + + String key = _children.get(_children.size() - 1).getID().toString(); + if(set.get(key) != null){ + return; + } + + buf.append(key); + + setColumn(_id.toString(),CHILDREN,buf.toString(),false); + } + + public void clearChildren(NodeID _id) + { + setColumn(_id.toString(),CHILDREN,"",false); + } + + public boolean removeChild(NodeID _id,Node _child) + { + String raw = getChildrenRaw(_id); + StringTokenizer token = new StringTokenizer(raw,CHILDREN_DELIM); + + CharBuffer buf = CharBuffer.allocate(raw.length()); + + boolean changed = false; + + while(token.hasMoreElements()){ + String child = token.nextToken(); + if(child.equals(_child.getID().toString())){ + changed = true; + continue; + } + + buf.append(child); + break; + } + + while(token.hasMoreElements()){ + String child = token.nextToken(); + if(child.equals(_child.getID().toString())){ + changed = true; + continue; + } + + buf.append(CHILDREN_DELIM+child); + } + + if(changed){ + setColumn(_id.toString(),CHILDREN,buf.toString(),false); + } + + return changed; + } + + public void replace(NodeID _id,Node _child1,Node _child2) + { + String children = getChildrenRaw(_id); + CharBuffer buf = CharBuffer.allocate(children.length()); + StringTokenizer tokens = new StringTokenizer(children,CHILDREN_DELIM); + + int flagSuccess = 0; + String id1 = _child1.getID().toString(); + String id2 = _child2.getID().toString(); + for(String prefix = "";tokens.hasMoreElements();prefix = CHILDREN_DELIM){ + String token = tokens.nextToken(); + if(token.equals(id1)){ + buf.append(prefix+id2); + flagSuccess++; + }else if(token.equals(id2)){ + buf.append(prefix+id1); + flagSuccess++; + }else{ + buf.append(prefix+token); + } + } + + if(flagSuccess == 2){ + setColumn(_id.toString(),CHILDREN,buf.toString(),false); + } + } + + public void down(NodeID _id,Node _child) { - return getColumn(_id.toString(),_colName,true); + String children = getChildrenRaw(_id); + String id = _child.getID().toString(); + CharBuffer buf = CharBuffer.allocate(children.length()); + StringTokenizer tokens = new StringTokenizer(children,CHILDREN_DELIM); + + for(String prefix = "";tokens.hasMoreElements();prefix = CHILDREN_DELIM){ + String token = tokens.nextToken(); + if(token.equals(id)){ + if(tokens.hasMoreElements()){ + buf.append(prefix+tokens.nextToken()); + prefix = CHILDREN_DELIM; + } + } + buf.append(prefix+token); + } + + setColumn(_id.toString(),CHILDREN,buf.toString(),false); + } + + public void up(NodeID _id,Node _child) + { + String children = getChildrenRaw(_id); + String id = _child.getID().toString(); + CharBuffer buf = CharBuffer.allocate(children.length()); + StringTokenizer tokens = new StringTokenizer(children,CHILDREN_DELIM); + + String prev = null; + String prefix = ""; + while(tokens.hasMoreElements()){ + if(prev == null){ + prev = tokens.nextToken(); + continue; + } + + String token = tokens.nextToken(); + if(token.equals(id)){ + buf.append(prefix+prev); + prev = token; + }else{ + buf.append(prefix+prev); + } + + prefix = CHILDREN_DELIM; + } + } + + public void setClassName(NodeID _id,String _className) + { + setColumn(_id.toString(),CLASSNAME,_className,false); + } + + public Node createNode() + { + return new CassNode(this,new CassDecNodeID(this)); + } + + public List getChildren(NodeID _id) + { + LinkedList children = new LinkedList(); + + String raw = getChildrenRaw(_id); + StringTokenizer tokens = new StringTokenizer(raw,CHILDREN_DELIM); + + while(tokens.hasMoreElements()){ + String first = tokens.nextToken(); + StringTokenizer sparator = new StringTokenizer(first,"@"); + String uuid = sparator.nextToken(); + long ver = Long.parseLong(sparator.nextToken()); + NodeID id = new CassDecNodeID(this,uuid,ver); + children.add(new CassNode(this,id)); + } + + return children; + } + + public CassNode cloneNode(NodeID _id) + { + NodeID newID = _id.update(); + + + return null; + } + + public CassLink createLink(NodeID _id) + { + return null; + } + + public boolean isChild(NodeID _id,Node _child) + { + String raw = getChildrenRaw(_id); + if(raw.indexOf(_child.getID().toString()) != -1){ + return true; + } + return false; + } + + public String getClassName(NodeID _id) + { + return getColumn(_id.toString(),CLASSNAME,false); + } + + public String getChildrenRaw(NodeID _id) + { + return getColumn(_id.toString(),CHILDREN,false); + } + + public String getTitle(NodeID _id) + { + return getColumn(_id.toString(),TITLE,false); + } + + public void setTitle(NodeID _id,String _title) + { + setColumn(_id.toString(),TITLE,_title,false); + } + + public String getAttribute(NodeID _id,String _attr) + { + return getColumn(_id.toString(),ATTR_PREFIX+_attr,false); + } + + public void setAttribute(NodeID _id,String _attr,String _value) + { + setColumn(_id.toString(),ATTR_PREFIX+_attr,_value,false); + } + + public Set getAttributeKeys(NodeID _id) + { + Set attrs = new HashSet(); + + SliceRange sr = new SliceRange(); + sr.setStart(new byte[0]); + sr.setFinish(new byte[0]); + + SlicePredicate sp = new SlicePredicate(); + sp.setSlice_range(sr); + + try{ + List columns = m_cassandra.get_slice(m_keySpace,_id.toString(),new ColumnParent(m_colFamily),sp,ConsistencyLevel.ONE); + for(ColumnOrSuperColumn column : columns){ + String key = new String(column.column.name); + if(key.startsWith(ATTR_PREFIX)){ + attrs.add(key); + } + } + }catch(Exception _e){ + _e.printStackTrace(); + } + + return attrs; } public NodeID getTipIDFromUUID(String _uuid) @@ -84,18 +355,12 @@ slicePredicate.setSlice_range(sliceRange); try { - List values = m_cassandra.get_range_slice(m_keySpace,new ColumnParent(m_colFamily),slicePredicate,"hogehoge","hogehogea",100,ConsistencyLevel.ONE); + List values = m_cassandra.get_range_slice(m_keySpace,new ColumnParent(m_colFamily),slicePredicate,"","",1,ConsistencyLevel.ONE); String key = values.get(0).getKey(); String tip = key.replaceFirst((_uuid+"@").intern(),""); return new CassDecNodeID(this,_uuid,Long.parseLong(tip)); - }catch(InvalidRequestException _e){ - _e.printStackTrace(); - }catch(UnavailableException _e){ - _e.printStackTrace(); - }catch(TimedOutException _e){ - _e.printStackTrace(); - }catch(TException _e){ + }catch(Exception _e){ _e.printStackTrace(); } @@ -120,6 +385,22 @@ return value; } + private boolean setColumn(String _row,String _colName,String _value,boolean _retry) + { + ColumnPath path = new ColumnPath(); + path.column_family = m_colFamily; + path.column = _colName.getBytes(); + + try{ + m_cassandra.insert(m_keySpace,_row,path,_value.getBytes(),System.currentTimeMillis()/1000,ConsistencyLevel.ONE); + return true; + }catch(Exception _e){ + _e.printStackTrace(); + } + + return false; + } + public CassNode createNode(String _id) { return null; @@ -128,6 +409,8 @@ @Override public Node useContents() { - return null; + String uuid = getColumn(TREEINFO,ROOTNODE,false); + NodeID rootID = getTipIDFromUUID(uuid); + return new CassNode(this,rootID); } } diff -r a529aad2ac92 -r 5b36891db5ca src/treecms/proto/cassandra/CassNode.java --- a/src/treecms/proto/cassandra/CassNode.java Sat Jan 22 22:55:19 2011 +0900 +++ b/src/treecms/proto/cassandra/CassNode.java Sat Jan 29 03:05:20 2011 +0900 @@ -1,8 +1,11 @@ package treecms.proto.cassandra; +import java.nio.CharBuffer; import java.util.Iterator; +import java.util.LinkedList; import java.util.List; import java.util.Set; +import java.util.StringTokenizer; import treecms.proto.api.Link; import treecms.proto.api.Node; @@ -11,137 +14,145 @@ public class CassNode implements Node { private CassBrowser m_browser; - private CassDecNodeID m_id; + private NodeID m_id; - public CassNode(CassBrowser _browser,CassDecNodeID _id) + public CassNode(CassBrowser _browser,NodeID _id) { m_browser = _browser; m_id = _id; } + + /* + * for implement connection pool + */ + private CassBrowser getBrowser() + { + return m_browser; + } @Override public Node addChild(Node _child) { - return null; - } - - @Override - public void addChildren(List _child) - { + return getBrowser().addChild(m_id,_child); } @Override - public void clearChildren() { - // TODO Auto-generated method stub - + public void addChildren(List _children) + { + getBrowser().addChildren(m_id,_children); + } + + @Override + public void clearChildren() + { + getBrowser().clearChildren(m_id); } @Override - public Node cloneNode() { - // TODO Auto-generated method stub - return null; + public Node cloneNode() + { + return getBrowser().cloneNode(m_id); } @Override - public Link createLink() { - // TODO Auto-generated method stub - return null; + public Link createLink() + { + return getBrowser().createLink(m_id); } @Override - public Node createNode() { - // TODO Auto-generated method stub - return null; + public Node createNode() + { + return getBrowser().createNode(); } @Override - public void down(Node child) { - // TODO Auto-generated method stub - + public void down(Node _child) + { + getBrowser().down(m_id,_child); } @Override - public String getAttribute(String attr) { - // TODO Auto-generated method stub - return null; + public String getAttribute(String _attr) + { + return getBrowser().getAttribute(m_id,_attr); } @Override - public Set getAttributeKeys() { - // TODO Auto-generated method stub - return null; + public Set getAttributeKeys() + { + return getBrowser().getAttributeKeys(m_id); } @Override - public List getChildren() { - // TODO Auto-generated method stub - return null; + public List getChildren() + { + return getBrowser().getChildren(m_id); } @Override - public String getClassName() { - // TODO Auto-generated method stub - return null; + public String getClassName() + { + return getBrowser().getClassName(m_id); } @Override - public NodeID getID() { - // TODO Auto-generated method stub - return null; + public NodeID getID() + { + return m_id; } @Override - public String getTitle() { - // TODO Auto-generated method stub - return null; + public String getTitle() + { + return getBrowser().getTitle(m_id); } @Override - public boolean isChild(Node child) { - // TODO Auto-generated method stub - return false; + public boolean isChild(Node _child) + { + return getBrowser().isChild(m_id,_child); } @Override - public Iterator iterator() { - // TODO Auto-generated method stub - return null; + public Iterator iterator() + { + return getChildren().iterator(); } @Override - public boolean removeChild(Node child) { - // TODO Auto-generated method stub - return false; + public boolean removeChild(Node _child) + { + return getBrowser().removeChild(m_id,_child); } @Override - public void replace(Node target, Node newChild) { - // TODO Auto-generated method stub - + public void replace(Node _target, Node _newChild) + { + getBrowser().replace(m_id,_target,_newChild); } @Override - public void setAttribute(String attr, String value) { - // TODO Auto-generated method stub - + public void setAttribute(String _attr, String _value) + { + getBrowser().setAttribute(m_id,_attr,_value); } @Override - public void setClassName(String class1) { - // TODO Auto-generated method stub - + public void setClassName(String _className) + { + getBrowser().setClassName(m_id,_className); } @Override - public void setTitle(String title) { - // TODO Auto-generated method stub - + public void setTitle(String _title) + { + getBrowser().setTitle(m_id,_title); } @Override - public void up(Node child) { - // TODO Auto-generated method stub - + public void up(Node _child) + { + getBrowser().up(m_id,_child); } - } diff -r a529aad2ac92 -r 5b36891db5ca src/treecms/proto/simple/SimpleDecNodeID.java --- a/src/treecms/proto/simple/SimpleDecNodeID.java Sat Jan 22 22:55:19 2011 +0900 +++ b/src/treecms/proto/simple/SimpleDecNodeID.java Sat Jan 29 03:05:20 2011 +0900 @@ -18,7 +18,7 @@ m_tip = new AtomicLong(); m_tip.set(START_VALUE); - m_version = m_tip.getAndDecrement(); + m_version = START_VALUE; } private SimpleDecNodeID(String _uuid,AtomicLong _tip,boolean _doUpdate) @@ -27,7 +27,7 @@ m_tip = _tip; if(_doUpdate){ - m_version = m_tip.getAndDecrement(); + m_version = m_tip.decrementAndGet(); return; } @@ -61,7 +61,6 @@ @Override public NodeID update() { - return new SimpleDecNodeID(m_uuid,m_tip,false); + return new SimpleDecNodeID(m_uuid,m_tip,true); } - }