Mercurial > hg > Members > shoshi > TreeCMS > TreeCMSPrototype1
view src/treecms/proto/cassandra/CassBrowser.java @ 47:5b36891db5ca
finished implementing cassandra monotonic tree
author | suika6039 |
---|---|
date | Sat, 29 Jan 2011 03:05:20 +0900 |
parents | 347feeca4728 |
children | ecba122dd3de |
line wrap: on
line source
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.transport.TTransport; import org.apache.thrift.transport.TFramedTransport; import org.apache.thrift.transport.TSocket; import org.apache.thrift.transport.TTransportException; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.cassandra.thrift.Cassandra; 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.KeySlice; import org.apache.cassandra.thrift.SlicePredicate; import org.apache.cassandra.thrift.SliceRange; public class CassBrowser implements Browser { 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; m_port = _port; m_cassandra = null; connect(); } public synchronized void connect() throws TTransportException { if(m_cassandra != null && m_cassandra.getOutputProtocol().getTransport().isOpen()){ return; } TTransport tr = new TFramedTransport(new TSocket(m_host,Integer.parseInt(m_port))); TProtocol proto = new TBinaryProtocol(tr); m_cassandra = new Cassandra.Client(proto); tr.open(); } public static CassBrowser createInstance(String _host,String _port,String _ks,String _cf) { CassBrowser browser = null; try{ browser = new CassBrowser(_host,_port); browser.m_keySpace = _ks; browser.m_colFamily = _cf; }catch(Exception _err){ _err.printStackTrace(); } return browser; } public Node addChild(NodeID _id,Node _child) { LinkedList<Node> tmp = new LinkedList<Node>(); tmp.add(_child); addChildren(_id,tmp); return _child; } public void addChildren(NodeID _id,List<Node> _children) { String children = getChildrenRaw(_id); Map<String,Boolean> set = new HashMap<String,Boolean>(); 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) { 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<Node> getChildren(NodeID _id) { LinkedList<Node> children = new LinkedList<Node>(); 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<String> getAttributeKeys(NodeID _id) { Set<String> attrs = new HashSet<String>(); SliceRange sr = new SliceRange(); sr.setStart(new byte[0]); sr.setFinish(new byte[0]); SlicePredicate sp = new SlicePredicate(); sp.setSlice_range(sr); try{ List<ColumnOrSuperColumn> 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) { SliceRange sliceRange = new SliceRange(); sliceRange.setStart(_uuid.getBytes()); sliceRange.setFinish(new byte[0]); SlicePredicate slicePredicate = new SlicePredicate(); slicePredicate.setSlice_range(sliceRange); try { List<KeySlice> 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(Exception _e){ _e.printStackTrace(); } return null; } private String getColumn(String _row,String _colName,boolean _retry) { ColumnPath path = new ColumnPath(); path.column_family = m_colFamily; path.column = _colName.getBytes(); String value = null; try{ ColumnOrSuperColumn column; column = m_cassandra.get(m_keySpace,_row,path,ConsistencyLevel.ONE); value = column.column.toString(); }catch(Exception _e){ _e.printStackTrace(); } 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; } @Override public Node useContents() { String uuid = getColumn(TREEINFO,ROOTNODE,false); NodeID rootID = getTipIDFromUUID(uuid); return new CassNode(this,rootID); } }