Mercurial > hg > Members > shoshi > jungle > jungle-core
changeset 4:761d04aecfcb
added Graph API and some implementation
line wrap: on
line diff
--- a/memo.txt Wed Jun 13 01:29:02 2012 +0900 +++ b/memo.txt Tue Jun 19 23:38:31 2012 +0900 @@ -21,4 +21,23 @@ ・ Node : Record の Property で Attribute を表現 ・ TreeGroup : Node で表すべき? ・ Tree : TreeNode を継承している よって Node で表す、 Children や Links は PropertySequence による. - ・ Link : Node で表す。 \ No newline at end of file + ・ Link : Node で表す。 + +2012/06/15 + ・Functional Java を使って PropertySequence を実装するといいかも? + ・Record , PropertySequence の hashCode , equals の実装について、ちゃんとテストを作ること!(重要) + ・なるべく、equals と hashCode はオーバーライドしないようにする、独自の比較メソッドを提供する。 + ・Table , Record , PropertySequence に Atomic なオペレーションを追加する + ・Table は Record の作成に CAS を追加する + ・Record は Map と PropertySequence に CAS を追加する。 + ・PropertySequence は・・・いらないか・・ + ・Jungle の API から getTreeGroups を削除した + ・Table , Record , PropertySequence では足りない、もっと美味いやりかたがあるはず + +2012/06/19 + ・Graph API を定義することにした + ・ Graph , Vertex , Vertexes + ・Neo4j で言うと + ・ GraphDB , Node , Iterator<Relationship> + ・とりあえずこれで実装してみる。 + ・今日は、SimpleVertexes をほぼ完成させた、あとすこしとテストコードを追加すること。 \ No newline at end of file
--- a/pom.xml Wed Jun 13 01:29:02 2012 +0900 +++ b/pom.xml Tue Jun 19 23:38:31 2012 +0900 @@ -36,6 +36,11 @@ <artifactId>jpf</artifactId> <version>1.5</version> </dependency> + <dependency> + <groupId>org.functionaljava</groupId> + <artifactId>functionaljava</artifactId> + <version>3.1</version> + </dependency> </dependencies> <build> <plugins>
--- a/src/main/java/jungle/core/Jungle.java Wed Jun 13 01:29:02 2012 +0900 +++ b/src/main/java/jungle/core/Jungle.java Tue Jun 19 23:38:31 2012 +0900 @@ -3,5 +3,4 @@ public interface Jungle { TreeGroup createTreeGroup(); - Iterable<TreeGroup> treeGroups(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/jungle/core/graph/Graph.java Tue Jun 19 23:38:31 2012 +0900 @@ -0,0 +1,13 @@ +package jungle.core.graph; + +import java.util.Iterator; + +public interface Graph +{ + public Vertex getVertex(String _id); + public Vertex createVertex(String _id); + public Vertex createVertex(); + + public boolean isSame(Graph _g); + public Iterator<Vertex> vertexes(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/jungle/core/graph/Vertex.java Tue Jun 19 23:38:31 2012 +0900 @@ -0,0 +1,16 @@ +package jungle.core.graph; + +public interface Vertex +{ + public String getID(); + public Graph getGraph(); + + public String getProperty(String _key); + public void setProperty(String _key,String _value); + public String removeProperty(String _key); + public boolean compareAndSwapProprety(String _key,String _except,String _value); + + public Vertexes removeVertexes(String _type); + public Vertexes getVertexes(String _type); + public Vertexes createVertexes(String _type); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/jungle/core/graph/Vertexes.java Tue Jun 19 23:38:31 2012 +0900 @@ -0,0 +1,28 @@ +package jungle.core.graph; + +import java.util.Collection; + +public interface Vertexes extends Iterable<Vertex> +{ + public int size(); + public Vertex at(int _i); + + public void add(Vertex _v); + public void add(Vertex _v,int _i); + public void add(Collection<Vertex> _vs); + public void add(Vertexes _vs); + + public void removeFirst(Vertex _v); + public void removeFirst(Collection<Vertex> _vs); + public void removeFirst(Vertexes _vs); + public void remove(int _i); + + public void replace(Vertex _v,int _i); + public void replaceFirst(Vertex _vertex,Vertex _newVertex); + + public boolean compareAndSwap(int _index,Vertex _vertex,Vertex _newVertex); + public boolean contains(Vertex _v); + + public Graph getGraph(); + public String type(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/jungle/core/graph/simple/SimpleGraph.java Tue Jun 19 23:38:31 2012 +0900 @@ -0,0 +1,83 @@ +package jungle.core.graph.simple; + +import java.util.Iterator; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicLong; + +import jungle.core.graph.Graph; +import jungle.core.graph.Vertex; + +public class SimpleGraph implements Graph +{ + private final AtomicLong ids; + private final ConcurrentHashMap<String,SimpleVertex> vertexes; + + public SimpleGraph() + { + ids = new AtomicLong(0); + vertexes = new ConcurrentHashMap<String,SimpleVertex>(); + } + + @Override + public Vertex createVertex() + { + SimpleVertex vertex,newVertex; + do{ + String id = Long.toString(ids.getAndIncrement()); + newVertex = new SimpleVertex(this,id); + vertex = vertexes.putIfAbsent(id,newVertex); + }while(vertex != null); + + return newVertex; + } + + @Override + public boolean isSame(Graph _g) + { + if(_g instanceof SimpleGraph){ + return _g == this; + } + + return false; + } + + @Override + public Vertex createVertex(String _id) + { + SimpleVertex vertex = new SimpleVertex(this,_id); + SimpleVertex value = vertexes.putIfAbsent(_id,vertex); + return value != null ? value : vertex; + } + + @Override + public Vertex getVertex(String _id) + { + return vertexes.get(_id); + } + + @Override + public Iterator<Vertex> vertexes() + { + final Iterator<SimpleVertex> itr = vertexes.values().iterator(); + Iterator<Vertex> wrapper = new Iterator<Vertex>(){ + @Override + public boolean hasNext() + { + return itr.hasNext(); + } + + @Override + public Vertex next() + { + return itr.next(); + } + + @Override + public void remove() + { + throw new UnsupportedOperationException("remove is not supported"); + } + }; + return wrapper; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/jungle/core/graph/simple/SimpleVertex.java Tue Jun 19 23:38:31 2012 +0900 @@ -0,0 +1,85 @@ +package jungle.core.graph.simple; + +import java.util.concurrent.ConcurrentHashMap; + +import jungle.core.graph.Graph; +import jungle.core.graph.Vertex; +import jungle.core.graph.Vertexes; + +public class SimpleVertex implements Vertex +{ + private String id; + private final SimpleGraph parent; + private final ConcurrentHashMap<String,String> properties; + private final ConcurrentHashMap<String,SimpleVertexes> relations; + + public SimpleVertex(SimpleGraph _parent,String _id) + { + id = _id; + parent = _parent; + properties = new ConcurrentHashMap<String,String>(); + relations = new ConcurrentHashMap<String,SimpleVertexes>(); + } + + void setID(String _id) + { + id = _id; + } + + @Override + public String getID() + { + return id; + } + + @Override + public String getProperty(String _key) + { + return properties.get(_key); + } + + @Override + public void setProperty(String _key, String _value) + { + properties.put(_key,_value); + } + + @Override + public String removeProperty(String _key) + { + return properties.remove(_key); + } + + @Override + public Vertexes getVertexes(String _key) + { + return relations.get(_key); + } + + @Override + public Vertexes removeVertexes(String _type) + { + SimpleVertexes vertexes = relations.remove(_type); + return vertexes; + } + + @Override + public boolean compareAndSwapProprety(String _key, String _except,String _value) + { + return properties.replace(_key,_except,_value); + } + + @Override + public Graph getGraph() + { + return parent; + } + + @Override + public Vertexes createVertexes(String _type) + { + SimpleVertexes vertexes = new SimpleVertexes(_type,parent); + SimpleVertexes result = relations.putIfAbsent(_type,vertexes); + return result == null ? vertexes : null; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/jungle/core/graph/simple/SimpleVertexes.java Tue Jun 19 23:38:31 2012 +0900 @@ -0,0 +1,376 @@ +package jungle.core.graph.simple; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.concurrent.atomic.AtomicReference; + +import fj.Equal; +import fj.F; +import fj.P2; +import fj.data.List; + +import jungle.core.graph.Graph; +import jungle.core.graph.Vertex; +import jungle.core.graph.Vertexes; + +public class SimpleVertexes implements Vertexes +{ + private final String type; + private final AtomicReference<List<SimpleVertex>> vertexes; + private final SimpleGraph parent; + + public SimpleVertexes(String _type,SimpleGraph _parent) + { + parent = _parent; + type = _type; + List<SimpleVertex> nil = List.nil(); + vertexes = new AtomicReference<List<SimpleVertex>>(nil); + } + + @Override + public void remove(final int _index) + { + List<SimpleVertex> current = null,update = null; + do{ + final List<SimpleVertex> list = vertexes.get(); + update = List.iterableList(new Iterable<SimpleVertex>(){ + @Override + public Iterator<SimpleVertex> iterator() { + return new Iterator<SimpleVertex>(){ + int count = 0; + Iterator<SimpleVertex> itr = list.iterator(); + + @Override + public boolean hasNext() + { + if(itr.hasNext() && count + 1 == _index){ + itr.next(); + } + + count ++; + return itr.hasNext(); + } + + @Override + public SimpleVertex next() + { + return itr.next(); + } + + @Override + public void remove() + { + throw new UnsupportedOperationException("removeing is not supported."); + } + }; + } + }); + }while(!vertexes.compareAndSet(current,update)); + } + + @Override + public int size() + { + return vertexes.get().length(); + } + + @Override + public Graph getGraph() + { + return parent; + } + + @Override + public void add(Vertex _v) + { + if(_v.getGraph() != parent){ + throw new IllegalArgumentException("Vertex _v is not belongs to same graph"); + } + + if(!(_v instanceof SimpleVertex)){ + throw new IllegalArgumentException("Vertex _v is not instanceof SimpleVertex"); + } + + List<SimpleVertex> cur,update; + do{ + cur = vertexes.get(); + update = cur.append(List.list((SimpleVertex)_v)); + }while(!vertexes.compareAndSet(cur,update)); + } + + @Override + public void add(Vertexes _vs) + { + if(!(_vs instanceof SimpleVertexes)){ + throw new IllegalArgumentException("Vertexes _vs is not instanceof SimpleVertex"); + } + + List<SimpleVertex> list = ((SimpleVertexes)_vs).vertexes.get(); + + List<SimpleVertex> cur,update; + do{ + cur = vertexes.get(); + update = cur.append(list); + }while(!vertexes.compareAndSet(cur,update)); + } + + @Override + public boolean contains(final Vertex _v) + { + if(_v.getGraph() == parent){ + throw new IllegalArgumentException("Vertex _v is not a number of graph"); + } + + List<SimpleVertex> list = vertexes.get(); + F<SimpleVertex,Boolean> predicate = new F<SimpleVertex,Boolean>(){ + @Override + public Boolean f(SimpleVertex _target) + { + return _v == _target; + } + }; + + return list.exists(predicate); + } + + @Override + public Iterator<Vertex> iterator() + { + List<SimpleVertex> list = vertexes.get(); + final Iterator<SimpleVertex> itr = list.iterator(); + Iterator<Vertex> wrapper = new Iterator<Vertex>(){ + + @Override + public boolean hasNext() + { + return itr.hasNext(); + } + + @Override + public Vertex next() + { + return itr.next(); + } + + @Override + public void remove() + { + throw new UnsupportedOperationException("removing is not supported"); + } + }; + + return wrapper; + } + + @Override + public String type() + { + return type; + } + + public static Equal<SimpleVertex> VERTEX_EQUAL = Equal.equal( + new F<SimpleVertex,F<SimpleVertex,Boolean>>(){ + @Override + public F<SimpleVertex, Boolean> f(final SimpleVertex _v1){ + return new F<SimpleVertex,Boolean>(){ + @Override + public Boolean f(SimpleVertex _v2){ + return _v1 == _v2; + } + }; + } + }); + + @Override + public void removeFirst(final Vertex _v) + { + if(_v == null){ + throw new NullPointerException("_v is null"); + } + + if(_v instanceof SimpleVertex){ + SimpleGraph g = (SimpleGraph)_v.getGraph(); + if(g != parent){ + throw new IllegalArgumentException("_v is not a part of graph"); + } + }else{ + throw new IllegalArgumentException("_v is not instanceof SimpleVertex it was " + _v.getClass().getName()); + } + + List<SimpleVertex> list,update; + do{ + list = vertexes.get(); + update = list.delete((SimpleVertex)_v,VERTEX_EQUAL); + }while(!vertexes.compareAndSet(list,update)); + } + + public Collection<Vertex> toCollection() + { + Collection<? extends Vertex> c = vertexes.get().toCollection(); + return Collections.unmodifiableCollection(c); + } + + @Override + public void removeFirst(Vertexes _vs) + { + if(_vs instanceof SimpleVertexes){ + Collection<Vertex> vs = ((SimpleVertexes)_vs).toCollection(); + removeFirst(vs); + } + } + + @Override + public void removeFirst(final Collection<Vertex> _vs) + { + if(_vs == null){ + throw new NullPointerException("_vs is null"); + } + + final HashSet<Vertex> tmp = new HashSet<Vertex>(_vs); + F<SimpleVertex,Boolean> predicate = new F<SimpleVertex,Boolean>(){ + @Override + public Boolean f(SimpleVertex _target) + { + return tmp.remove(_target); + } + }; + + List<SimpleVertex> list,update; + do{ + list = vertexes.get(); + update = list.removeAll(predicate); + }while(!vertexes.compareAndSet(list,update)); + } + + @Override + public Vertex at(int _index) + { + List<SimpleVertex> list = vertexes.get(); + + if(list.length() < _index){ + throw new IndexOutOfBoundsException("vertex.length() < _index"); + } + + return list.take(_index).last(); + } + + @Override + public void add(Vertex _v, int _index) + { + + if(_v instanceof SimpleVertex){ + throw new IllegalArgumentException("_v is not a SimpleVertex"); + } + + + List<SimpleVertex> list = null,update = null; + do{ + list = vertexes.get(); + if(list.length() < _index){ + throw new IndexOutOfBoundsException("vertex.length() < _index"); + } + P2<List<SimpleVertex>,List<SimpleVertex>> slice = list.splitAt(_index); + + update = slice._1().snoc((SimpleVertex)_v).append(slice._2()); + }while(!vertexes.compareAndSet(list,update)); + } + + @Override + public void add(Collection<Vertex> _vs) + { + final Iterator<Vertex> itr = _vs.iterator(); + Iterable<SimpleVertex> wrapper = new Iterable<SimpleVertex>(){ + @Override + public Iterator<SimpleVertex> iterator() { + return new Iterator<SimpleVertex>(){ + @Override + public boolean hasNext(){ + return itr.hasNext(); + } + @Override + public SimpleVertex next(){ + Vertex v = itr.next(); + if(!(v instanceof SimpleVertex)){ + throw new IllegalArgumentException("_vs is including not a SimpleVertex instance."); + } + + if(v.getGraph() == parent){ + throw new IllegalArgumentException("_vs has vertex from other graph instance"); + } + return (SimpleVertex)v; + } + @Override + public void remove(){ + throw new UnsupportedOperationException("removeing is not supported."); + } + }; + } + }; + + List<SimpleVertex> a = List.iterableList(wrapper); + + List<SimpleVertex> current = null,update = null; + do{ + current = vertexes.get(); + update = current.append(a); + }while(!vertexes.compareAndSet(current,update)); + } + + @Override + public void replace(Vertex _v, int _index) + { + if(_v == null){ + throw new NullPointerException("_v is null"); + } + + if(!(_v instanceof SimpleVertex)){ + throw new IllegalArgumentException("_v is not a instanceof SimpleVertex"); + } + + List<SimpleVertex> current = null,update = null; + do{ + current = vertexes.get(); + if(current.length() < _index){ + throw new IndexOutOfBoundsException("current.length() < _index"); + } + + P2<List<SimpleVertex>,List<SimpleVertex>> slice = current.splitAt(_index); + update = slice._1().snoc((SimpleVertex)_v).append(slice._2().drop(1)); + }while(!vertexes.compareAndSet(current,update)); + } + + @Override + public void replaceFirst(final Vertex _vertex, Vertex _newVertex) + { + if(_vertex == null || _newVertex == null){ + throw new NullPointerException("_vertex or _newVertex is null"); + } + + if(!(_vertex instanceof SimpleVertex) || !(_newVertex instanceof SimpleVertex)){ + throw new IllegalArgumentException("_v is not a instanceof SimpleVertex"); + } + + F<SimpleVertex,Boolean> predicate = new F<SimpleVertex,Boolean>(){ + @Override + public Boolean f(SimpleVertex _vertex2){ + return _vertex != _vertex2; + } + }; + + List<SimpleVertex> current = null,update = null; + do{ + P2<List<SimpleVertex>,List<SimpleVertex>> slice = current.span(predicate); + if(slice._2().length() != 0){ + //TODO , next day write here. + } + }while(!vertexes.compareAndSet(current,update)); + } + + @Override + public boolean compareAndSwap(int _index, Vertex _vertex, Vertex _newVertex) + { + return false; + } +}
--- a/src/main/java/jungle/core/table/PropertySequence.java Wed Jun 13 01:29:02 2012 +0900 +++ b/src/main/java/jungle/core/table/PropertySequence.java Tue Jun 19 23:38:31 2012 +0900 @@ -5,5 +5,6 @@ public void add(String _value); public String get(int _pos); public String remove(int _pos); + public boolean isSameSequence(PropertySequence _seq); public int size(); }
--- a/src/main/java/jungle/core/table/Record.java Wed Jun 13 01:29:02 2012 +0900 +++ b/src/main/java/jungle/core/table/Record.java Tue Jun 19 23:38:31 2012 +0900 @@ -12,7 +12,14 @@ public PropertySequence createSequence(String _key); public PropertySequence getSequence(String _key); public PropertySequence removeSequence(String _key); + public void setSequence(String _key,PropertySequence _seq); public Iterator<Pair<String,String>> properties(); public Iterator<Pair<String,PropertySequence>> sequences(); + + /* + * for concurrent purpose + */ + public boolean compareAndSwapProperty(String _key,String _expect,String _value); + public PropertySequence createSequenceIfAbsent(String _key); }
--- a/src/main/java/jungle/core/table/Table.java Wed Jun 13 01:29:02 2012 +0900 +++ b/src/main/java/jungle/core/table/Table.java Tue Jun 19 23:38:31 2012 +0900 @@ -5,4 +5,6 @@ public Record create(String _key); public Record find(String _key); public Record remove(String _key); + + public Record findAndCreateIfNotExist(String _key); }
--- a/src/main/java/jungle/core/table/simple/SimplePropertySequence.java Wed Jun 13 01:29:02 2012 +0900 +++ b/src/main/java/jungle/core/table/simple/SimplePropertySequence.java Tue Jun 19 23:38:31 2012 +0900 @@ -3,6 +3,7 @@ import java.util.Collection; import java.util.Collections; import java.util.Iterator; +import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import javax.annotation.concurrent.ThreadSafe; @@ -19,6 +20,12 @@ sequence = new CopyOnWriteArrayList<String>(); readonlyWrapper = Collections.unmodifiableCollection(sequence); } + + private SimplePropertySequence(List<String> _copyTarget) + { + sequence = new CopyOnWriteArrayList<String>(_copyTarget); + readonlyWrapper = Collections.unmodifiableCollection(sequence); + } @Override public Iterator<String> iterator() @@ -29,6 +36,10 @@ @Override public void add(String _value) { + if(_value == null){ + throw new NullPointerException("_value == null"); + } + sequence.add(_value); } @@ -49,5 +60,38 @@ { return sequence.size(); } + + public boolean isSameSequence(PropertySequence _obj) + { + // suspicious + if(_obj instanceof PropertySequence){ + PropertySequence seq = (PropertySequence)_obj; + if(seq.size() != size()){ + return false; + } + + Iterator<String> itr1 = seq.iterator(); + Iterator<String> itr2 = this.iterator(); + + while(itr1.hasNext() && itr2.hasNext()){ + String s1 = itr1.next(); + String s2 = itr2.next(); + + if(!s1.equals(s2)){ + return false; + } + } + + if(itr1.hasNext() == itr2.hasNext()){ + return true; + } + } + + return false; + } + SimplePropertySequence snapshot() + { + return new SimplePropertySequence(sequence); + } } \ No newline at end of file
--- a/src/main/java/jungle/core/table/simple/SimpleRecord.java Wed Jun 13 01:29:02 2012 +0900 +++ b/src/main/java/jungle/core/table/simple/SimpleRecord.java Tue Jun 19 23:38:31 2012 +0900 @@ -15,12 +15,12 @@ public class SimpleRecord implements Record { private final ConcurrentHashMap<String,String> properties; - private final ConcurrentHashMap<String,PropertySequence> sequences; + private final ConcurrentHashMap<String,SimplePropertySequence> sequences; public SimpleRecord() { properties = new ConcurrentHashMap<String,String>(); - sequences = new ConcurrentHashMap<String,PropertySequence>(); + sequences = new ConcurrentHashMap<String,SimplePropertySequence>(); } @Override @@ -60,6 +60,14 @@ { return sequences.remove(_key); } + + @Override + public void setSequence(String _key,PropertySequence _seq) + { + if(_seq instanceof SimplePropertySequence){ + + } + } @Override public Iterator<Pair<String, String>> properties() @@ -92,8 +100,8 @@ @Override public Iterator<Pair<String, PropertySequence>> sequences() { - final Set<Entry<String,PropertySequence>> entries = sequences.entrySet(); - final Iterator<Entry<String,PropertySequence>> itr = entries.iterator(); + final Set<Entry<String,SimplePropertySequence>> entries = sequences.entrySet(); + final Iterator<Entry<String,SimplePropertySequence>> itr = entries.iterator(); return new Iterator<Pair<String,PropertySequence>>(){ @Override @@ -105,7 +113,7 @@ @Override public Pair<String, PropertySequence> next() { - Entry<String,PropertySequence> ent = itr.next(); + Entry<String,SimplePropertySequence> ent = itr.next(); return new Pair<String,PropertySequence> (ent.getKey(),ent.getValue()); } @@ -116,4 +124,18 @@ } }; } + + @Override + public boolean compareAndSwapProperty(String _key, String _expect,String _value) + { + return properties.replace(_key,_expect,_value); + } + + @Override + public PropertySequence createSequenceIfAbsent(String _key) + { + SimplePropertySequence seq = new SimplePropertySequence(); + SimplePropertySequence old = sequences.putIfAbsent(_key,seq); + return old != null ? old : seq; + } }
--- a/src/main/java/jungle/core/table/simple/SimpleTable.java Wed Jun 13 01:29:02 2012 +0900 +++ b/src/main/java/jungle/core/table/simple/SimpleTable.java Tue Jun 19 23:38:31 2012 +0900 @@ -7,11 +7,11 @@ public class SimpleTable implements Table { - private final ConcurrentHashMap<String,Record> table; + private final ConcurrentHashMap<String,SimpleRecord> table; public SimpleTable() { - table = new ConcurrentHashMap<String,Record>(); + table = new ConcurrentHashMap<String,SimpleRecord>(); } @Override @@ -33,4 +33,12 @@ { return table.remove(_key); } + + @Override + public Record findAndCreateIfNotExist(String _key) + { + SimpleRecord r = new SimpleRecord(); + SimpleRecord find = table.putIfAbsent(_key,r); + return find != null ? find : r; + } }
--- a/src/main/java/jungle/impl/SimpleChildren.java Wed Jun 13 01:29:02 2012 +0900 +++ b/src/main/java/jungle/impl/SimpleChildren.java Tue Jun 19 23:38:31 2012 +0900 @@ -11,7 +11,7 @@ { private final OrderedNodeSet<TreeNode> sets; - public SimpleChildren() + public SimpleChildren(PropertySequence _seq) { this(new SimpleOrderedNodeSet<TreeNode>()); }
--- a/src/main/java/jungle/impl/SimpleJungle.java Wed Jun 13 01:29:02 2012 +0900 +++ b/src/main/java/jungle/impl/SimpleJungle.java Tue Jun 19 23:38:31 2012 +0900 @@ -1,31 +1,25 @@ package jungle.impl; -import java.util.Collections; import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; - import jungle.core.Jungle; import jungle.core.TreeGroup; +import jungle.core.table.Record; +import jungle.core.table.Table; public class SimpleJungle implements Jungle { - private final ConcurrentHashMap<String,TreeGroup> treeGroups; + private final Table tb; - public SimpleJungle() + public SimpleJungle(Table _tb) { - treeGroups = new ConcurrentHashMap<String,TreeGroup>(); + tb = _tb; } public TreeGroup createTreeGroup() { - String tid = UUID.randomUUID().toString(); - SimpleTreeGroup g = new SimpleTreeGroup(tid); - treeGroups.put(tid,g); - return g; - } - - public Iterable<TreeGroup> treeGroups() - { - return Collections.unmodifiableCollection(treeGroups.values()); + String groupID = UUID.randomUUID().toString(); + Record tg = tb.create(groupID); + + return new SimpleTreeGroup(groupID,tg,tb); } }
--- a/src/main/java/jungle/impl/SimpleTree.java Wed Jun 13 01:29:02 2012 +0900 +++ b/src/main/java/jungle/impl/SimpleTree.java Tue Jun 19 23:38:31 2012 +0900 @@ -6,27 +6,24 @@ import jungle.core.Links; import jungle.core.Tree; import jungle.core.TreeGroup; +import jungle.core.table.Record; public class SimpleTree implements Tree { - private final String tid; - private final Attributes attrs; - private final Children children; - private final Links links; + private final String treeID; private final TreeGroup group; + private final Record record; - public SimpleTree(String _tid,TreeGroup _group) + private final SimpleChildren children; + private final SimpleLinks links; + + public SimpleTree(TreeGroup _group,String _treeID,Record _r) { - this(_tid,_group,Simples.EMPTY_ATTRIBUTES,Simples.EMPTY_CHILDREN,Simples.EMPTY_LINKS); - } - - public SimpleTree(String _tid,TreeGroup _group,Attributes _attrs,Children _children,Links _links) - { - tid = _tid; - attrs = _attrs; - children = _children; - links = _links; + treeID = _treeID; group = _group; + record = _r; + children = new SimpleChildren(_r.createSequenceIfAbsent(Simples.TREENODE_CHILDREN_KEY)); + links = new SimpleLinks(_r.createSequenceIfAbsent(Simples.TREENODE_LINKS_KEY)); } public TreeGroup getGroup() @@ -36,12 +33,12 @@ public String get(String _key) { - return attrs.get(_key); + return record.getProperty(Simples.PROPERTY_KEY_PREFIX+_key); } public String treeID() { - return tid; + return treeID; } public Children children() @@ -56,6 +53,6 @@ public String cid() { - return tid; + return treeID; } }
--- a/src/main/java/jungle/impl/SimpleTreeGroup.java Wed Jun 13 01:29:02 2012 +0900 +++ b/src/main/java/jungle/impl/SimpleTreeGroup.java Tue Jun 19 23:38:31 2012 +0900 @@ -6,28 +6,36 @@ import jungle.core.Editor; import jungle.core.Tree; import jungle.core.TreeGroup; +import jungle.core.table.Record; +import jungle.core.table.Table; public class SimpleTreeGroup implements TreeGroup { - private String id; - private AtomicReference<Tree> latestTree; - private AtomicLong revisionCounter; + private final String groupID; + private final Record record; + private final AtomicLong revisionCounter; + private final Table table; - public SimpleTreeGroup(String _id) + public SimpleTreeGroup(String _groupID,Record _r,Table _tb) { - latestTree = new AtomicReference<Tree>(); - id = _id; + groupID = _groupID; + record = _r; + table = _tb; revisionCounter = new AtomicLong(); } public String getID() { - return id; + return groupID; } public Tree latestTree() { - return latestTree.get(); + String treeID = record.getProperty(Simples.TREEGROUP_TIP_TREE_KEY); + String key = String.format(Simples.TREEGROUP_TREEID_FORMAT,groupID,treeID); + Record r = table.find(key); + SimpleTree tip = new SimpleTree(this,treeID,r); + return tip; } public String newTreeID()
--- a/src/main/java/jungle/impl/SimpleTreeNode.java Wed Jun 13 01:29:02 2012 +0900 +++ b/src/main/java/jungle/impl/SimpleTreeNode.java Tue Jun 19 23:38:31 2012 +0900 @@ -4,69 +4,44 @@ import jungle.core.Children; import jungle.core.Links; import jungle.core.TreeNode; +import jungle.core.table.Record; public class SimpleTreeNode implements TreeNode { - private final Children children; - private final Links links; - private final Attributes attrs; + private final Record record; private final String id; - public SimpleTreeNode(String _id) + public SimpleTreeNode(String _id,Record _r) { - this(_id,new SimpleAttributes(),new SimpleChildren(),new SimpleLinks()); - } - - private SimpleTreeNode(String _id,Attributes _attrs,Children _children,Links _links) - { - if(_id == null || _id.length() == 0){ - throw new NullPointerException("_id is null or empty."); + if(_id == null || _r == null){ + throw new NullPointerException("_id == null || _r == null"); } id = _id; - attrs = _attrs; - children = _children; - links = _links; + record = _r; } - public String get(String _key) - { - if(_key == null){ - throw new NullPointerException("_key is null"); - } - - return attrs.get(_key); - } - - public Children children() - { - return children; + @Override + public String get(String _key) { + // TODO Auto-generated method stub + return null; } - public Links links() - { - return links; - } - - public String cid() - { - return id; - } - @Override - public int hashCode() - { - return id.hashCode(); - } - - @Override - public boolean equals(Object _obj) - { - if(_obj instanceof SimpleTreeNode){ - SimpleTreeNode node = (SimpleTreeNode)_obj; - return id.equals(node.id); - } - return false; + public Children children() { + // TODO Auto-generated method stub + return null; } + @Override + public Links links() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String cid() { + // TODO Auto-generated method stub + return null; + } }
--- a/src/main/java/jungle/impl/Simples.java Wed Jun 13 01:29:02 2012 +0900 +++ b/src/main/java/jungle/impl/Simples.java Tue Jun 19 23:38:31 2012 +0900 @@ -9,4 +9,14 @@ public static final Attributes EMPTY_ATTRIBUTES = new SimpleAttributes(); public static final Children EMPTY_CHILDREN = new SimpleChildren(); public static final Links EMPTY_LINKS = new SimpleLinks(); + + public static final String PROPERTY_KEY_PREFIX = "@"; + + public static final String TREENODE_CHILDREN_KEY = "CHILDREN"; + public static final String TREENODE_LINKS_KEY = "LINKS"; + + public static final String LINK_DESTINATION_KEY = "DESTINATION"; + + public static final String TREEGROUP_TIP_TREE_KEY = "TIP"; + public static final String TREEGROUP_TREEID_FORMAT = "%s@%s"; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/test/java/jungle/core/graph/AbstractGraphTest.java Tue Jun 19 23:38:31 2012 +0900 @@ -0,0 +1,68 @@ +package jungle.core.graph; + + +import java.util.HashSet; +import java.util.Iterator; +import junit.framework.Assert; +import junit.framework.TestCase; + +public abstract class AbstractGraphTest extends TestCase +{ + public abstract Graph newInstance(); + + public void testGraphIsSame() + { + Graph g1 = newInstance(); + Graph g2 = newInstance(); + + Assert.assertTrue(g1.isSame(g1)); + Assert.assertFalse(g1.isSame(g2)); + } + + public void testGetVertex() + { + Graph g = newInstance(); + Vertex v = g.createVertex("ONE"); + Assert.assertEquals(v,g.getVertex("ONE")); + Assert.assertNull(g.getVertex("TWO")); + + Vertex v2 = g.createVertex(); + String id = v2.getID(); + Assert.assertEquals(v2,g.getVertex(id)); + } + + public void testCreateVertex() + { + Graph g = newInstance(); + + Vertex v1 = g.createVertex("ONE"); + Vertex v2 = g.createVertex("TWO"); + Vertex v3 = g.createVertex("THREE"); + Vertex v4 = g.createVertex(); + + Assert.assertNotNull(v1); + Assert.assertNotNull(v2); + Assert.assertNotNull(v3); + Assert.assertNotNull(v4); + } + + public void testIterateVertex() + { + Graph g = newInstance(); + + Vertex v1 = g.createVertex("ONE"); + Vertex v2 = g.createVertex("TWO"); + Vertex v3 = g.createVertex("THREE"); + + HashSet<Vertex> vs = new HashSet<Vertex>(); + vs.add(v1); + vs.add(v2); + vs.add(v3); + + Iterator<Vertex> itr = g.vertexes(); + while(itr.hasNext()){ + Vertex v = itr.next(); + Assert.assertTrue(vs.remove(v)); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/test/java/jungle/core/graph/AbstractVertexTest.java Tue Jun 19 23:38:31 2012 +0900 @@ -0,0 +1,115 @@ +package jungle.core.graph; + +import junit.framework.Assert; +import junit.framework.TestCase; + +public abstract class AbstractVertexTest extends TestCase +{ + public abstract Vertex newInstance(); + + public void testProperty() + { + Vertex v = newInstance(); + + v.setProperty("KEY","VALUE"); + Assert.assertEquals("VALUE",v.getProperty("KEY")); + + v.removeProperty("KEY"); + Assert.assertNull(v.getProperty("KEY")); + } + + public void testGetGraph() + { + Vertex v = newInstance(); + Graph g = v.getGraph(); + + Assert.assertNotNull(g); + } + + public void testGetIDAndTryToResolveFromParentGraph() + { + Vertex v = newInstance(); + Graph g = v.getGraph(); + String id = v.getID(); + + Assert.assertNotNull(id); + Assert.assertEquals(v,g.getVertex(id)); + } + + public void testGetVertexes() + { + Vertex v = newInstance(); + Vertexes vs1 = v.getVertexes("RELATIONS"); + Assert.assertNull("vs1 is null",vs1); + + v.createVertexes("RELATIONS"); + vs1 = v.getVertexes("RELATIONS"); + Assert.assertNotNull(vs1); + + Vertexes vs2 = v.getVertexes("RELATIONS"); + Assert.assertEquals(vs1,vs2); + } + + public void testCreateVertexes() + { + Vertex v = newInstance(); + Vertexes vs = v.createVertexes("RELATIONS"); + // check that vs is correctly created. + Assert.assertNotNull(vs); + Assert.assertEquals(vs.type(),"RELATIONS"); + + // createVertexes must return null , if vertexes is already exist. + Assert.assertNull(v.createVertexes("RELATIONS")); + } + + public void testRemoveVertexes() + { + Vertex v = newInstance(); + Vertexes vs1 = v.createVertexes("RELATIONS"); + Assert.assertNotNull("vs1 is null",vs1); + + v.removeVertexes("RELATIONS"); + + Assert.assertNull("removed Vertexes must be null",v.getVertexes("RELATIONS")); + } + + public void testRemovePropertyRefuseNull() + { + Vertex v = newInstance(); + + try{ + v.removeProperty(null); + }catch(NullPointerException _e){ + return; + } + + Assert.fail(); + } + + public void testSetPropertyRefuseNull() + { + Vertex v = newInstance(); + + try{ + v.setProperty(null,"VALUE"); + v.setProperty("KEY",null); + }catch(NullPointerException _e){ + return; + } + + Assert.fail(); + } + + public void testGetPropertyRefuseNull() + { + Vertex v = newInstance(); + + try{ + v.getProperty(null); + }catch(NullPointerException _e){ + return; + } + + Assert.fail(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/test/java/jungle/core/graph/AbstractVertexesTest.java Tue Jun 19 23:38:31 2012 +0900 @@ -0,0 +1,191 @@ +package jungle.core.graph; + +import java.util.Collection; +import java.util.HashSet; + +import junit.framework.Assert; +import junit.framework.TestCase; + +public abstract class AbstractVertexesTest extends TestCase +{ + public abstract Graph newInstance(); + + public void testSize() + { + Graph g = newInstance(); + Vertex v = g.createVertex(); + Vertexes vs = v.createVertexes("RELATIONS"); + + Assert.assertEquals(0,vs.size()); + + Vertex c1 = g.createVertex(); + vs.add(c1); + Assert.assertEquals(1,vs.size()); + + Vertex c2 = g.createVertex(); + vs.add(c2); + Assert.assertEquals(2,vs.size()); + + Vertex c3 = g.createVertex(); + vs.add(c3); + Assert.assertEquals(3,vs.size()); + + vs.remove(c3); + Assert.assertEquals(2,vs.size()); + } + + public void testAddingDoesNotAcceptOtherGraphVertex() + { + Graph g1 = newInstance(); + Graph g2 = newInstance(); + + Vertex v1 = g1.createVertex(); + Vertex v2 = g2.createVertex(); + + Vertexes vs = v1.createVertexes("RELATIONS"); + try{ + // v2 belongs to g2 , but v1 is not belongs to g2 + vs.add(v2); // should be fail here. + }catch(IllegalArgumentException _e){ + return; + } + + Assert.fail("testing add() does not accept other graph vertex fail."); + } + + public void testAddSingleVertex() + { + Graph g = newInstance(); + Vertex v = g.createVertex(); + Vertex c = g.createVertex(); + Vertexes vs = v.createVertexes("RELATIONS"); + + vs.add(c); + + for(Vertex i : vs){ + Assert.assertEquals(c,i); + } + } + + public void testAddRefuseNull() + { + Graph g = newInstance(); + Vertex v = g.createVertex(); + Vertexes vs = v.createVertexes("RELATIONS"); + + try{ + vs.add((Vertex)null); + Assert.fail("vs.add(Vertex) didnt throw null pointer exception"); + }catch(NullPointerException _e){ + // do nothing. + } + + try{ + vs.add((Collection<Vertex>)null); + }catch(NullPointerException _e){ + return; + } + Assert.fail("vs.add(Collection<Vertex> didnt throw null pointer exception"); + } + + public void testAddVertexCollection() + { + Graph g = newInstance(); + Vertex v = g.createVertex(); + Vertexes vs = v.createVertexes("RELATIONS"); + + HashSet<Vertex> set = new HashSet<Vertex>(); + set.add(g.createVertex()); + set.add(g.createVertex()); + set.add(g.createVertex()); + + vs.add(set); + Assert.assertEquals(3,vs.size()); + + for(Vertex x : vs){ + Assert.assertTrue("adding collection to Vertexes , but verification was failed.",set.contains(x)); + } + } + + public void testRemoveSingleVertex() + { + Graph g = newInstance(); + Vertex v = g.createVertex(); + Vertexes vs = v.createVertexes("RELATIONS"); + + HashSet<Vertex> set = new HashSet<Vertex>(); + set.add(g.createVertex()); + set.add(g.createVertex()); + set.add(g.createVertex()); + + Vertex c = g.createVertex(); + vs.add(c); + Assert.assertEquals(4,vs.size()); + + vs.remove(c); + Assert.assertEquals(3,vs.size()); + + for(Vertex x : vs){ + Assert.assertTrue(set.contains(x)); + } + + Assert.assertEquals(0,set.size()); + } + + public void testRemoveVertexRefuseNull() + { + Graph g = newInstance(); + Vertexes vs = g.createVertex().createVertexes("RELATIONS"); + + try{ + vs.remove((Vertex)null); + Assert.fail("vs.remove(Vertex) didnt throw null pointer exception"); + }catch(NullPointerException _e){ + // do nothing. + } + + try{ + vs.remove((Collection<Vertex>)null); + }catch(NullPointerException _e){ + return; + } + Assert.fail("vs.remove(Collection<Vertex> didnt throw null pointer exception"); + } + + public void testRemoveVertexCollection() + { + Graph g = newInstance(); + Vertexes vs = g.createVertex().createVertexes("RELATIONS"); + + HashSet<Vertex> set = new HashSet<Vertex>(); + set.add(g.createVertex()); + set.add(g.createVertex()); + set.add(g.createVertex()); + + vs.add(set); + Assert.assertEquals(3,vs.size()); + + vs.remove(set); + Assert.assertEquals(0,vs.size()); + } + + public void testContains() + { + Graph g = newInstance(); + Vertexes vs = g.createVertex().createVertexes("RELATIONS"); + + Vertex v = g.createVertex(); + vs.add(v); + vs.add(g.createVertex()); + + Assert.assertTrue(vs.contains(v)); + } + + public void testVertexType() + { + Graph g = newInstance(); + Vertexes vs = g.createVertex().createVertexes("RELATIONS"); + + Assert.assertEquals("RELATIONS",vs.type()); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/test/java/jungle/core/graph/simple/SimpleGraphTest.java Tue Jun 19 23:38:31 2012 +0900 @@ -0,0 +1,13 @@ +package jungle.core.graph.simple; + +import jungle.core.graph.AbstractGraphTest; +import jungle.core.graph.Graph; + +public class SimpleGraphTest extends AbstractGraphTest +{ + @Override + public Graph newInstance() + { + return new SimpleGraph(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/test/java/jungle/core/graph/simple/SimpleVertexTest.java Tue Jun 19 23:38:31 2012 +0900 @@ -0,0 +1,20 @@ +package jungle.core.graph.simple; + +import jungle.core.graph.AbstractVertexTest; +import jungle.core.graph.Vertex; + +public class SimpleVertexTest extends AbstractVertexTest +{ + private final SimpleGraph g; + + public SimpleVertexTest() + { + g = new SimpleGraph(); + } + + @Override + public Vertex newInstance() + { + return g.createVertex(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/test/java/jungle/core/graph/simple/SimpleVertexesTest.java Tue Jun 19 23:38:31 2012 +0900 @@ -0,0 +1,13 @@ +package jungle.core.graph.simple; + +import jungle.core.graph.AbstractVertexesTest; +import jungle.core.graph.Graph; + +public class SimpleVertexesTest extends AbstractVertexesTest +{ + @Override + public Graph newInstance() + { + return new SimpleGraph(); + } +}
--- a/src/test/java/jungle/core/table/AbstractPropertySequenceTestTemplate.java Wed Jun 13 01:29:02 2012 +0900 +++ b/src/test/java/jungle/core/table/AbstractPropertySequenceTestTemplate.java Tue Jun 19 23:38:31 2012 +0900 @@ -27,6 +27,18 @@ return seq; } + public void testAddIsNotAcceptNullValue() + { + PropertySequence seq = newInstance(); + try{ + seq.add(null); + Assert.fail("seq.add(null) does not throw NullPointerException"); + }catch(NullPointerException _e){ + Assert.assertTrue(true); + } + + } + public void testAdd() { PropertySequence seq = prepare();
--- a/src/test/java/jungle/core/table/AbstractRecordTestTemplate.java Wed Jun 13 01:29:02 2012 +0900 +++ b/src/test/java/jungle/core/table/AbstractRecordTestTemplate.java Tue Jun 19 23:38:31 2012 +0900 @@ -29,6 +29,26 @@ return r; } + public void testCompareAndSwapProperty() + { + Record r = newInstance(); + + r.setProperty(ONE,ONE); + Assert.assertFalse(r.compareAndSwapProperty(ONE,THREE,THREE)); + Assert.assertTrue(r.compareAndSwapProperty(ONE,ONE,TWO)); + Assert.assertEquals(r.getProperty(ONE),TWO); + } + + public void testCreateSequenceIfAbsent() + { + Record r = newInstance(); + + PropertySequence one = r.createSequence(ONE); + Assert.assertEquals(one,r.createSequenceIfAbsent(ONE)); + Assert.assertNull(r.getProperty(TWO)); + Assert.assertNotNull(r.createSequenceIfAbsent(TWO)); + } + public void testSetProperty() { Record r = prepare(); @@ -37,6 +57,19 @@ Assert.assertEquals(r.getProperty("TEST"),"TEST"); } + public void testNullProperty() + { + Record r = newInstance(); + try{ + r.setProperty(null,"hoge"); + r.setProperty("hoge",null); + + Assert.fail("r.setProperty(null,v) or r.setProperty(k,null) does not throw NullPointerException"); + }catch(NullPointerException _e){ + Assert.assertTrue(true); + } + } + public void testGetProperty() { Record r = prepare();
--- a/src/test/java/jungle/core/table/AbstractTableTestTemplate.java Wed Jun 13 01:29:02 2012 +0900 +++ b/src/test/java/jungle/core/table/AbstractTableTestTemplate.java Tue Jun 19 23:38:31 2012 +0900 @@ -22,6 +22,18 @@ public static final String TWO = "two"; public static final String THREE = "three"; + public void testFindRecordAndCreateIfNotExist() + { + Table t = newInstance(); + + Record one = t.create(ONE); + Assert.assertEquals(one,t.findAndCreateIfNotExist(ONE)); + + Record four = t.find("four"); + Assert.assertNull(four); + Assert.assertNotNull(t.findAndCreateIfNotExist("four")); + } + public void testCreateRecord() { Table t = newInstance(); @@ -42,6 +54,7 @@ Record one = t.create(ONE); Assert.assertNotNull(one); Assert.assertEquals(one,t.find(ONE)); + Assert.assertNull(t.find("NOENTRY")); } public void testRemoveRecord()
--- a/src/test/java/jungle/core/table/simple/SimplePropertySequenceTest.java Wed Jun 13 01:29:02 2012 +0900 +++ b/src/test/java/jungle/core/table/simple/SimplePropertySequenceTest.java Tue Jun 19 23:38:31 2012 +0900 @@ -1,13 +1,27 @@ package jungle.core.table.simple; import jungle.core.table.AbstractPropertySequenceTestTemplate; -import jungle.core.table.PropertySequence; +import junit.framework.Assert; public class SimplePropertySequenceTest extends AbstractPropertySequenceTestTemplate { @Override - public PropertySequence newInstance() + public SimplePropertySequence newInstance() { return new SimplePropertySequence(); } + + public void testSnapshot() + { + SimplePropertySequence seq = newInstance(); + + seq.add("hoge"); + + SimplePropertySequence ss = seq.snapshot(); + Assert.assertNotNull(ss); + Assert.assertTrue(ss.isSameSequence(seq)); + + ss.add("hoge2"); + Assert.assertFalse(ss.isSameSequence(seq)); + } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/test/java/jungle/misc/fj/ImmutableListExample.java Tue Jun 19 23:38:31 2012 +0900 @@ -0,0 +1,43 @@ +package jungle.misc.fj; + +import fj.Equal; +import fj.F; +import fj.P2; +import fj.data.List; + +public class ImmutableListExample +{ + public static void main(String[] _args) + { + List<String> first = List.list("1","3","2","3"); + List<String> two = first.snoc("4"); + F<String,Boolean> predicate = new F<String,Boolean>(){ + @Override + public Boolean f(String arg0) + { + return "3".equals(arg0); + } + }; + + List<String> three = two.removeAll(predicate); + List<String> four = two.delete("3",Equal.equal( + new F<String,F<String,Boolean>>(){ + @Override + public F<String, Boolean> f(final String _str){ + return new F<String,Boolean>(){ + @Override + public Boolean f(String _str1){ + return _str.equals(_str1); + } + }; + } + })); + + System.out.println(first.toString()); + System.out.println(two.toString()); + P2<List<String>,List<String>> p = two.splitAt(2); + System.out.println(p._1().snoc("hey!").append(p._2()).toString()); + System.out.println(three.toString()); + System.out.println(four.toString()); + } +}