Author: jpz6311whu
Date: Sun Jun 15 15:53:23 2014
New Revision: 1602713

URL: http://svn.apache.org/r1602713
Log:
1) modify PropertyTable API, with javadoc added
2) implement PropertyTableImpl with HashMap, including the indexes of PSO and 
POS 

Modified:
    jena/Experimental/jena-csv/pom.xml
    
jena/Experimental/jena-csv/src/main/java/com/hp/hpl/jena/propertytable/Column.java
    
jena/Experimental/jena-csv/src/main/java/com/hp/hpl/jena/propertytable/PropertyTable.java
    
jena/Experimental/jena-csv/src/main/java/com/hp/hpl/jena/propertytable/Row.java
    
jena/Experimental/jena-csv/src/main/java/com/hp/hpl/jena/propertytable/impl/ColumnImpl.java
    
jena/Experimental/jena-csv/src/main/java/com/hp/hpl/jena/propertytable/impl/GraphPropertyTable.java
    
jena/Experimental/jena-csv/src/main/java/com/hp/hpl/jena/propertytable/impl/PropertyTableBuilder.java
    
jena/Experimental/jena-csv/src/main/java/com/hp/hpl/jena/propertytable/impl/PropertyTableImpl.java
    
jena/Experimental/jena-csv/src/test/java/com/hp/hpl/jena/propertytable/impl/GraphCSVTest.java
    jena/Experimental/jena-csv/src/test/resources/test.csv

Modified: jena/Experimental/jena-csv/pom.xml
URL: 
http://svn.apache.org/viewvc/jena/Experimental/jena-csv/pom.xml?rev=1602713&r1=1602712&r2=1602713&view=diff
==============================================================================
--- jena/Experimental/jena-csv/pom.xml (original)
+++ jena/Experimental/jena-csv/pom.xml Sun Jun 15 15:53:23 2014
@@ -50,7 +50,14 @@
       <version>2.12.0-SNAPSHOT</version>
       <type>pom</type>
     </dependency>
-
+    
+    <!-- Google Code Guava -->
+    <dependency>
+         <groupId>com.googlecode.guava-osgi</groupId>
+         <artifactId>guava-osgi</artifactId>
+         <version>11.0.0</version>
+       </dependency>   
+       
     <!-- Testing support -->
     <dependency>
       <groupId>org.apache.jena</groupId>

Modified: 
jena/Experimental/jena-csv/src/main/java/com/hp/hpl/jena/propertytable/Column.java
URL: 
http://svn.apache.org/viewvc/jena/Experimental/jena-csv/src/main/java/com/hp/hpl/jena/propertytable/Column.java?rev=1602713&r1=1602712&r2=1602713&view=diff
==============================================================================
--- 
jena/Experimental/jena-csv/src/main/java/com/hp/hpl/jena/propertytable/Column.java
 (original)
+++ 
jena/Experimental/jena-csv/src/main/java/com/hp/hpl/jena/propertytable/Column.java
 Sun Jun 15 15:53:23 2014
@@ -19,10 +19,20 @@ package com.hp.hpl.jena.propertytable;
 
 import com.hp.hpl.jena.graph.Node;
 
+/**
+ * Each Column of the PropertyTable has an unique columnKey Node of the 
predicate (or p for short).
+ * 
+ */
 public interface Column {
 
+       /**
+        * @return the PropertyTable it belongs to
+        */
        PropertyTable getTable();
 
-       Node getNode();
+       /**
+        * @return the columnKey Node of the predicate
+        */
+       Node getColumnKey();
 
 }

Modified: 
jena/Experimental/jena-csv/src/main/java/com/hp/hpl/jena/propertytable/PropertyTable.java
URL: 
http://svn.apache.org/viewvc/jena/Experimental/jena-csv/src/main/java/com/hp/hpl/jena/propertytable/PropertyTable.java?rev=1602713&r1=1602712&r2=1602713&view=diff
==============================================================================
--- 
jena/Experimental/jena-csv/src/main/java/com/hp/hpl/jena/propertytable/PropertyTable.java
 (original)
+++ 
jena/Experimental/jena-csv/src/main/java/com/hp/hpl/jena/propertytable/PropertyTable.java
 Sun Jun 15 15:53:23 2014
@@ -23,17 +23,74 @@ import com.hp.hpl.jena.graph.Node;
 import com.hp.hpl.jena.graph.Triple;
 import com.hp.hpl.jena.util.iterator.ExtendedIterator;
 
+/**
+ * PropertyTable is designed to be a table of RDF terms, or Nodes in Jena. 
+ * Each Column of the PropertyTable has an unique columnKey Node of the 
predicate (or p for short).
+ * Each Row of the PropertyTable has an unique rowKey Node of the subject (or 
s for short).
+ * You can use getColumn() to get the Column by its columnKey Node of the 
predicate, while getRow() for Row.
+ * 
+ */
 public interface PropertyTable {
        
-       ExtendedIterator<Triple> getTripleIterator();
-
+       /**
+        * Query for ?s <p> <o>
+        * @param column, the Column with the columnKey Node of the predicate
+        * @param value, the object (or value) Node
+        * @return the ExtendedIterator of the matching Triples
+        */
+       ExtendedIterator<Triple> getTripleIterator(Column column, Node value);
+
+       /**
+        * Query for ?s <p> ?o
+        * @param column, the Column with the columnKey Node of the predicate
+        * @return the ExtendedIterator of the matching Triples
+        */
        ExtendedIterator<Triple> getTripleIterator(Column column);
+       
+       /**
+        * Query for ?s ?p <o>
+        * @param value, the object (or value) Node
+        * @return the ExtendedIterator of the matching Triples
+        */
+       ExtendedIterator<Triple> getTripleIterator(Node value);
+       
+       /**
+        * Query for <s> ?p ?o
+        * @param row, the Row with the rowKey Node of the subject
+        * @return the ExtendedIterator of the matching Triples
+        */
+       ExtendedIterator<Triple> getTripleIterator(Row row);
+       
+       /**
+        * Query for ?s ?p ?o
+        * @return all of the Triples of the PropertyTable
+        */
+       ExtendedIterator<Triple> getTripleIterator();
 
+       /**
+        * @return all of the Columns of the PropertyTable
+        */
        Collection<Column> getColumns();
 
+       /**
+        * Get Column by its columnKey Node of the predicate
+        * @param p, columnKey Node of the predicate
+        * @return the Column
+        */
        Column getColumn(Node p);
 
+       /**
+        * Create a Column by its columnKey Node of the predicate
+        * @param p
+        */
        void createColumn(Node p);
 
-       Row getRow(Object rowNum);
+       /**
+        * Get Row by its rowKey Node of the subject
+        * @param s, rowKey Node of the subject
+        * @return the Row
+        */
+       Row getRow(Node s);
+       
+       
 }

Modified: 
jena/Experimental/jena-csv/src/main/java/com/hp/hpl/jena/propertytable/Row.java
URL: 
http://svn.apache.org/viewvc/jena/Experimental/jena-csv/src/main/java/com/hp/hpl/jena/propertytable/Row.java?rev=1602713&r1=1602712&r2=1602713&view=diff
==============================================================================
--- 
jena/Experimental/jena-csv/src/main/java/com/hp/hpl/jena/propertytable/Row.java 
(original)
+++ 
jena/Experimental/jena-csv/src/main/java/com/hp/hpl/jena/propertytable/Row.java 
Sun Jun 15 15:53:23 2014
@@ -19,9 +19,42 @@
 package com.hp.hpl.jena.propertytable;
 
 import com.hp.hpl.jena.graph.Node;
+import com.hp.hpl.jena.graph.Triple;
+import com.hp.hpl.jena.util.iterator.ExtendedIterator;
 
+/**
+ * Each Row of the PropertyTable has an unique rowKey Node of the subject (or 
s for short).
+ *
+ */
 public interface Row {
 
-       void set(Node p, Node value);
+       /**
+        * @return the PropertyTable it belongs to
+        */
+       PropertyTable getTable();
+       
+       /**
+        * Set the value of the Column in this Row
+        * @param column
+        * @param value
+        */
+       void setValue(Column column, Node value);
+       
+       /**
+        * Get the value of the Column in this Row
+        * @param column
+        * @return value
+        */
+       Node getValue(Column column);
+       
+       /**
+        * @return the rowKey Node of the subject
+        */
+       Node getRowKey();
+       
+       /**
+        * @return the Triple Iterator over the values in this Row
+        */
+       ExtendedIterator<Triple> getTripleIterator();
 
 }

Modified: 
jena/Experimental/jena-csv/src/main/java/com/hp/hpl/jena/propertytable/impl/ColumnImpl.java
URL: 
http://svn.apache.org/viewvc/jena/Experimental/jena-csv/src/main/java/com/hp/hpl/jena/propertytable/impl/ColumnImpl.java?rev=1602713&r1=1602712&r2=1602713&view=diff
==============================================================================
--- 
jena/Experimental/jena-csv/src/main/java/com/hp/hpl/jena/propertytable/impl/ColumnImpl.java
 (original)
+++ 
jena/Experimental/jena-csv/src/main/java/com/hp/hpl/jena/propertytable/impl/ColumnImpl.java
 Sun Jun 15 15:53:23 2014
@@ -37,7 +37,7 @@ public class ColumnImpl implements Colum
        }
 
        @Override
-       public Node getNode() {
+       public Node getColumnKey() {
                return p;
        }
 }

Modified: 
jena/Experimental/jena-csv/src/main/java/com/hp/hpl/jena/propertytable/impl/GraphPropertyTable.java
URL: 
http://svn.apache.org/viewvc/jena/Experimental/jena-csv/src/main/java/com/hp/hpl/jena/propertytable/impl/GraphPropertyTable.java?rev=1602713&r1=1602712&r2=1602713&view=diff
==============================================================================
--- 
jena/Experimental/jena-csv/src/main/java/com/hp/hpl/jena/propertytable/impl/GraphPropertyTable.java
 (original)
+++ 
jena/Experimental/jena-csv/src/main/java/com/hp/hpl/jena/propertytable/impl/GraphPropertyTable.java
 Sun Jun 15 15:53:23 2014
@@ -41,77 +41,89 @@ public class GraphPropertyTable extends 
 
        @Override
        protected ExtendedIterator<Triple> graphBaseFind(TripleMatch m) {
+               //System.out.println(m);
 
                if (this.pt == null) {
                        return NullIterator.instance();
                }
-               
-               ExtendedIterator<Triple> iter= null;
+
+               ExtendedIterator<Triple> iter = null;
+
+               Node s = m.getMatchSubject();
                Node p = m.getMatchPredicate();
-               
-               
-               if (p == null || p == Node.ANY) {
-                       iter = pt.getTripleIterator();
-               } else {
+               Node o = m.getMatchObject();
+
+               if (isConcrete(p) && isConcrete(o)) {
+                       //System.out.println("1");
+                       iter = pt.getTripleIterator(pt.getColumn(p), o);
+               } else if (isConcrete(p)) {
+                       //System.out.println("2");
                        Column column = this.pt.getColumn(p);
-                       if (column !=null){
-                               iter = pt.getTripleIterator();
-                       }else {
+                       if (column != null) {
+                               iter = pt.getTripleIterator(column);
+                       } else {
                                return NullIterator.instance();
                        }
+               } else if (isConcrete(o)) {
+                       //System.out.println("3");
+                       iter = pt.getTripleIterator(o);
+               } else{
+                       //System.out.println("4");
+                       iter = pt.getTripleIterator();
+               }
+
+               return iter.filterKeep(new 
TripleMatchFilterEquality(m.asTriple()));
+
+       }
+
+       static class TripleMatchFilterEquality extends Filter<Triple> {
+               final protected Triple tMatch;
+
+               /** Creates new TripleMatchFilter */
+               public TripleMatchFilterEquality(Triple tMatch) {
+                       this.tMatch = tMatch;
                }
-               
-               return iter.filterKeep ( new TripleMatchFilterEquality( 
m.asTriple() ) );
 
+               @Override
+               public boolean accept(Triple t) {
+                       return tripleContained(tMatch, t);
+               }
+
+       }
+
+       static boolean tripleContained(Triple patternTriple, Triple dataTriple) 
{
+               return equalNode(patternTriple.getSubject(), 
dataTriple.getSubject())
+                               && equalNode(patternTriple.getPredicate(),
+                                               dataTriple.getPredicate())
+                               && equalNode(patternTriple.getObject(), 
dataTriple.getObject());
+       }
+
+       private static boolean equalNode(Node m, Node n) {
+               // m should not be null unless .getMatchXXXX used to get the 
node.
+               // Language tag canonicalization
+               n = fixupNode(n);
+               m = fixupNode(m);
+               return (m == null) || (m == Node.ANY) || m.equals(n);
+       }
+
+       private static Node fixupNode(Node node) {
+               if (node == null || node == Node.ANY)
+                       return node;
+
+               // RDF says ... language tags should be canonicalized to lower 
case.
+               if (node.isLiteral()) {
+                       String lang = node.getLiteralLanguage();
+                       if (lang != null && !lang.equals(""))
+                               node = 
NodeFactory.createLiteral(node.getLiteralLexicalForm(),
+                                               lang.toLowerCase(Locale.ROOT),
+                                               node.getLiteralDatatype());
+               }
+               return node;
+       }
+
+       private boolean isConcrete(Node node) {
+               boolean wild = (node == null || node == Node.ANY);
+               return !wild;
        }
-       
-       static class TripleMatchFilterEquality extends Filter<Triple>
-    {
-        final protected Triple tMatch;
-    
-        /** Creates new TripleMatchFilter */
-        public TripleMatchFilterEquality(Triple tMatch) 
-            { this.tMatch = tMatch; }
-        
-        @Override
-        public boolean accept(Triple t)
-        {
-            return tripleContained(tMatch, t) ;
-        }
-        
-    }
-       static boolean tripleContained(Triple patternTriple, Triple dataTriple)
-    {
-        return
-            equalNode(patternTriple.getSubject(),   dataTriple.getSubject()) &&
-            equalNode(patternTriple.getPredicate(), dataTriple.getPredicate()) 
&&
-            equalNode(patternTriple.getObject(),    dataTriple.getObject()) ;
-    }
-    
-    private static boolean equalNode(Node m, Node n)
-    {
-        // m should not be null unless .getMatchXXXX used to get the node.
-        // Language tag canonicalization
-        n = fixupNode(n) ;
-        m = fixupNode(m) ;
-        return (m==null) || (m == Node.ANY) || m.equals(n) ;
-    }
-    
-    private static Node fixupNode(Node node)
-    {
-        if ( node == null || node == Node.ANY )
-            return node ;
-
-        // RDF says ... language tags should be canonicalized to lower case.
-        if ( node.isLiteral() )
-        {
-            String lang = node.getLiteralLanguage() ;
-            if ( lang != null && ! lang.equals("") )
-                node = NodeFactory.createLiteral(node.getLiteralLexicalForm(),
-                                          lang.toLowerCase(Locale.ROOT),
-                                          node.getLiteralDatatype()) ;
-        }
-        return node ; 
-    }
 
 }

Modified: 
jena/Experimental/jena-csv/src/main/java/com/hp/hpl/jena/propertytable/impl/PropertyTableBuilder.java
URL: 
http://svn.apache.org/viewvc/jena/Experimental/jena-csv/src/main/java/com/hp/hpl/jena/propertytable/impl/PropertyTableBuilder.java?rev=1602713&r1=1602712&r2=1602713&view=diff
==============================================================================
--- 
jena/Experimental/jena-csv/src/main/java/com/hp/hpl/jena/propertytable/impl/PropertyTableBuilder.java
 (original)
+++ 
jena/Experimental/jena-csv/src/main/java/com/hp/hpl/jena/propertytable/impl/PropertyTableBuilder.java
 Sun Jun 15 15:53:23 2014
@@ -23,6 +23,7 @@ import java.util.List;
 
 import org.apache.jena.atlas.csv.CSVParser;
 import org.apache.jena.riot.lang.LangCSV;
+import org.apache.jena.riot.system.IRIResolver;
 
 import com.hp.hpl.jena.datatypes.xsd.XSDDatatype;
 import com.hp.hpl.jena.graph.Node;
@@ -32,47 +33,52 @@ import com.hp.hpl.jena.propertytable.Row
 import com.hp.hpl.jena.util.FileUtils;
 
 public class PropertyTableBuilder {
-       
-       
+
        public static Node CSV_ROW_NODE = 
NodeFactory.createURI(LangCSV.CSV_ROW);
-       
-       public static PropertyTable buildPropetyTableFromCSVFile(String 
csvFilePath){
+
+       public static PropertyTable buildPropetyTableFromCSVFile(String 
csvFilePath) {
 
                CSVParser parser = CSVParser.create(csvFilePath);
                PropertyTableImpl table = new PropertyTableImpl();
-               
-               List<String> rowLine = null ;
+
+               List<String> rowLine = null;
                ArrayList<Node> predicates = new ArrayList<Node>();
                int rowNum = 0;
-               
-               while ( (rowLine=parser.parse1())!=null) {
-                        if (rowNum==0){
-                                table.createColumn(CSV_ROW_NODE);
-                                for (String column: rowLine){
-                                        Node p = 
NodeFactory.createURI(FileUtils.toURL(csvFilePath) + "#" + column.trim());
-                                        predicates.add(p);
-                                        table.createColumn(p);
-                                }
-                        }else {
-                                Row row = table.getRow(rowNum);
-                                row.set(CSV_ROW_NODE, 
NodeFactory.createLiteral( (rowNum+"").trim(), XSDDatatype.XSDinteger) );
-                        
-                                for (int col=0;col<rowLine.size();col++){
-                                        
-                                        String columnValue = 
rowLine.get(col).trim();
-                                        Node o ;
-                                        try { 
-                                                // Try for a double.
-                                                double d = 
Double.parseDouble(columnValue);
-                                                o = 
NodeFactory.createLiteral(columnValue, XSDDatatype.XSDdouble) ;
-                                        } catch(Exception e) {
-                                                o = 
NodeFactory.createLiteral(columnValue) ;
-                                        }
-                                        row.set( predicates.get(col) , o);
-                                }
-                        }
-                        rowNum++;
+
+               while ((rowLine = parser.parse1()) != null) {
+                       if (rowNum == 0) {
+                               table.createColumn(CSV_ROW_NODE);
+                               for (String column : rowLine) {
+                                       String uri = 
IRIResolver.resolveString(csvFilePath) + "#"
+                                                       + 
LangCSV.toSafeLocalname(column);
+                                       Node p = NodeFactory.createURI(uri);
+                                       predicates.add(p);
+                                       table.createColumn(p);
+                               }
+                       } else {
+                               Node subject = LangCSV.caculateSubject(rowNum, 
csvFilePath);
+                               Row row = table.getRow(subject);
+                               
+                               row.setValue(table.getColumn(CSV_ROW_NODE), 
NodeFactory.createLiteral(
+                                               (rowNum + ""), 
XSDDatatype.XSDinteger));
+
+                               for (int col = 0; col < rowLine.size(); col++) {
+
+                                       String columnValue = 
rowLine.get(col).trim();
+                                       Node o;
+                                       try {
+                                               // Try for a double.
+                                               double d = 
Double.parseDouble(columnValue);
+                                               o = 
NodeFactory.createLiteral(columnValue,
+                                                               
XSDDatatype.XSDdouble);
+                                       } catch (Exception e) {
+                                               o = 
NodeFactory.createLiteral(columnValue);
+                                       }
+                                       
row.setValue(table.getColumn(predicates.get(col)), o);
+                               }
+                       }
+                       rowNum++;
                }
                return table;
-       }       
+       }
 }

Modified: 
jena/Experimental/jena-csv/src/main/java/com/hp/hpl/jena/propertytable/impl/PropertyTableImpl.java
URL: 
http://svn.apache.org/viewvc/jena/Experimental/jena-csv/src/main/java/com/hp/hpl/jena/propertytable/impl/PropertyTableImpl.java?rev=1602713&r1=1602712&r2=1602713&view=diff
==============================================================================
--- 
jena/Experimental/jena-csv/src/main/java/com/hp/hpl/jena/propertytable/impl/PropertyTableImpl.java
 (original)
+++ 
jena/Experimental/jena-csv/src/main/java/com/hp/hpl/jena/propertytable/impl/PropertyTableImpl.java
 Sun Jun 15 15:53:23 2014
@@ -24,39 +24,58 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Set;
 
 import org.apache.jena.atlas.iterator.Iter;
 import org.apache.jena.atlas.iterator.IteratorConcat;
 
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.SetMultimap;
 import com.hp.hpl.jena.graph.Node;
-import com.hp.hpl.jena.graph.NodeFactory;
 import com.hp.hpl.jena.graph.Triple;
 import com.hp.hpl.jena.propertytable.Column;
 import com.hp.hpl.jena.propertytable.PropertyTable;
 import com.hp.hpl.jena.propertytable.Row;
-import com.hp.hpl.jena.rdf.model.AnonId;
 import com.hp.hpl.jena.util.iterator.ExtendedIterator;
 import com.hp.hpl.jena.util.iterator.WrappedIterator;
 
+/**
+ * A PropertyTable Implementation using HashMap.
+ * It contains PSO and POS indexes.
+ * 
+ */
 public class PropertyTableImpl implements PropertyTable {
 
-       private Map<Node, Column> columnIndex; // Maps property Node to Column
+       private Map<Node, Column> columnIndex; // Maps property Node key to 
Column
        private List<Column> columnList; // Stores the list of columns in the 
table
-       private Map<Object, Row> rowIndex; // Maps the row number to Row.
+       private Map<Node, Row> rowIndex; // Maps the subject Node key to Row.
        private List<Row> rowList; // Stores the list of rows in the table
-       private Map<Node, Map<Object, Node>> valueIndex; // Maps column Node to
-                                                                               
                                // (rowNum,value) pairs
+
+       // PSO index
+       private Map<Node, Map<Node, Node>> valueIndex; // Maps column Node to
+                                                                               
                        // (subject Node, value)
+                                                                               
                        // pairs
+       // POS index
+       private Map<Node, SetMultimap<Node, Node>> valueReverseIndex; // Maps 
column
+                                                                               
                                                        // Node to
+                                                                               
                                                        // (value,
+                                                                               
                                                        // subject
+                                                                               
                                                        // Node)
+                                                                               
                                                        // pairs
 
        PropertyTableImpl() {
                columnIndex = new HashMap<Node, Column>();
                columnList = new ArrayList<Column>();
-               rowIndex = new HashMap<Object, Row>();
+               rowIndex = new HashMap<Node, Row>();
                rowList = new ArrayList<Row>();
-               valueIndex = new HashMap<Node, Map<Object, Node>>();
+               valueIndex = new HashMap<Node, Map<Node, Node>>();
+               valueReverseIndex = new HashMap<Node, SetMultimap<Node, 
Node>>();
        }
 
        @Override
        public ExtendedIterator<Triple> getTripleIterator() {
+               
+               // use PSO index to scan all the table (slow)
                IteratorConcat<Triple> iter = new IteratorConcat<Triple>();
                for (Column column : getColumns()) {
                        iter.add(getTripleIterator(column));
@@ -66,20 +85,54 @@ public class PropertyTableImpl implement
 
        @Override
        public ExtendedIterator<Triple> getTripleIterator(Column column) {
-               ArrayList<Triple> triples = new ArrayList<Triple>();
-               Map<Object, Node> values = valueIndex.get(column.getNode());
                
-               for(Entry<Object,Node> entry :values.entrySet()){
-                       
-                       Object rowNum = entry.getKey();
-                       Node s  = NodeFactory.createAnon(AnonId.create( 
"_:"+rowNum  ));
+               // use PSO index directly (fast)
+               ArrayList<Triple> triples = new ArrayList<Triple>();
+               Map<Node, Node> values = valueIndex.get(column.getColumnKey());
+
+               for (Entry<Node, Node> entry : values.entrySet()) {
+                       Node subject = entry.getKey();
                        Node value = entry.getValue();
-                       triples.add( Triple.create(s, column.getNode(), value) 
);
+                       triples.add(Triple.create(subject, 
column.getColumnKey(), value));
                }
                return WrappedIterator.create(triples.iterator());
        }
 
        @Override
+       public ExtendedIterator<Triple> getTripleIterator(Node value) {
+               
+               // use POS index ( O(n), n= column count )
+               IteratorConcat<Triple> iter = new IteratorConcat<Triple>();
+               for (Column column : this.getColumns()) {
+                       ExtendedIterator<Triple> eIter = 
getTripleIterator(column);
+                       iter.add(eIter);
+               }
+               return WrappedIterator.create(Iter.distinct(iter));
+       }
+
+       @Override
+       public ExtendedIterator<Triple> getTripleIterator(Column column, Node 
value) {
+               
+               // use POS index directly (fast)
+               Node p = column.getColumnKey();
+               final SetMultimap<Node, Node> valueToSubjectMap = 
valueReverseIndex
+                               .get(p);
+               final Set<Node> subjects = valueToSubjectMap.get(value);
+               ArrayList<Triple> triples = new ArrayList<Triple>();
+               for (Node subject : subjects) {
+                       triples.add(Triple.create(subject, p, value));
+               }
+               return WrappedIterator.create(triples.iterator());
+       }
+
+
+       @Override
+       public ExtendedIterator<Triple> getTripleIterator(Row row) {
+               // use PSO index ( O(n), n= column count )
+               return row.getTripleIterator();
+       }
+
+       @Override
        public Collection<Column> getColumns() {
                return columnList;
        }
@@ -100,68 +153,119 @@ public class PropertyTableImpl implement
 
                columnIndex.put(p, new ColumnImpl(this, p));
                columnList.add(columnIndex.get(p));
-               valueIndex.put(p, new HashMap<Object, Node>());
+               valueIndex.put(p, new HashMap<Node, Node>());
+               valueReverseIndex.put(p, HashMultimap.<Node, Node> create());
        }
 
        @Override
-       public Row getRow(final Object rowNum) {
-               if (rowNum == null)
-                       throw new NullPointerException("row number is null");
-               Row row = rowIndex.get(rowNum);
+       public Row getRow(final Node s) {
+               if (s == null)
+                       throw new NullPointerException("subject node is null");
+               Row row = rowIndex.get(s);
                if (row != null)
                        return row;
 
-               row = new InternalRow(rowNum);
-               rowIndex.put(rowNum, row);
+               row = new InternalRow(s);
+               rowIndex.put(s, row);
                rowList.add(row);
 
                return row;
        }
 
-       private final void setX(final Object rowNum, final Node p, final Node 
value) {
+       private final void setX(final Node s, final Node p, final Node value) {
                if (p == null)
                        throw new NullPointerException("column Node must not be 
null.");
                if (value == null)
                        throw new NullPointerException("value must not be 
null.");
 
-               if (columnIndex.get(p) == null)
+               Map<Node, Node> subjectToValueMap = valueIndex.get(p);
+               if (!columnIndex.containsKey(p) || subjectToValueMap == null)
                        throw new IllegalArgumentException("column: '" + p
                                        + "' does not yet exist.");
 
-               Map<Object, Node> rowNumToValueMap = valueIndex.get(p);
-               
-               rowNumToValueMap.put(rowNum, value);
-               
+               Node oldValue = subjectToValueMap.get(s);
+               subjectToValueMap.put(s, value);
+               addToReverseMap(p, s, oldValue, value);
        }
 
-       private void unSetX(final Object rowNum, final Node p) {
+       private void addToReverseMap(final Node p, final Node s,
+                       final Node oldValue, final Node value) {
 
-               final Map<Object, Node> rowNumToValueMap = valueIndex.get(p);
-               if (!columnIndex.containsKey(p) || rowNumToValueMap == null)
+               final SetMultimap<Node, Node> valueToSubjectMap = 
valueReverseIndex
+                               .get(p);
+               valueToSubjectMap.remove(oldValue, s);
+               valueToSubjectMap.put(value, s);
+       }
+
+       private void unSetX(final Node s, final Node p) {
+
+               final Map<Node, Node> subjectToValueMap = valueIndex.get(p);
+               if (!columnIndex.containsKey(p) || subjectToValueMap == null)
                        throw new IllegalArgumentException("column: '" + p
                                        + "' does not yet exist.");
 
-               final Object value = rowNumToValueMap.get(rowNum);
+               final Node value = subjectToValueMap.get(s);
                if (value == null)
                        return;
-               
-               rowNumToValueMap.remove(rowNum);
 
+               subjectToValueMap.remove(s);
+               removeFromReverseMap(p, s, value);
+       }
+
+       private void removeFromReverseMap(final Node p, final Node s,
+                       final Node value) {
+               final SetMultimap<Node, Node> valueTokeysMap = 
valueReverseIndex.get(p);
+               valueTokeysMap.remove(s, value);
+       }
+
+       private Node getX(final Node s, final Node p) {
+               final Map<Node, Node> subjectToValueMap = valueIndex.get(p);
+               if (!columnIndex.containsKey(p) || subjectToValueMap == null)
+                       throw new IllegalArgumentException("column: '" + p
+                                       + "' does not yet exist.");
+               return subjectToValueMap.get(s);
        }
 
        private final class InternalRow implements Row {
-               private final Object key;
+               private final Node key;
 
-               InternalRow(final Object key) {
+               InternalRow(final Node key) {
                        this.key = key;
                }
 
                @Override
-               public void set(Node p, Node value) {
+               public void setValue(Column column, Node value) {
                        if (value == null)
-                               unSetX(key, p);
+                               unSetX(key, column.getColumnKey());
                        else
-                               setX(key, p, value);
+                               setX(key, column.getColumnKey(), value);
+               }
+
+               @Override
+               public Node getValue(Column column) {
+                       return getX(key, column.getColumnKey());
+               }
+
+               @Override
+               public PropertyTable getTable() {
+                       return PropertyTableImpl.this;
+               }
+
+               @Override
+               public Node getRowKey() {
+                       return key;
+               }
+
+               @Override
+               public ExtendedIterator<Triple> getTripleIterator() {
+                       ArrayList<Triple> triples = new ArrayList<Triple>();
+                       for (Column column : getColumns()) {
+                               Node value = this.getValue(column);
+                               triples.add(Triple.create(key, 
column.getColumnKey(), value));
+                       }
+                       return WrappedIterator.create(triples.iterator());
                }
+
        }
+
 }

Modified: 
jena/Experimental/jena-csv/src/test/java/com/hp/hpl/jena/propertytable/impl/GraphCSVTest.java
URL: 
http://svn.apache.org/viewvc/jena/Experimental/jena-csv/src/test/java/com/hp/hpl/jena/propertytable/impl/GraphCSVTest.java?rev=1602713&r1=1602712&r2=1602713&view=diff
==============================================================================
--- 
jena/Experimental/jena-csv/src/test/java/com/hp/hpl/jena/propertytable/impl/GraphCSVTest.java
 (original)
+++ 
jena/Experimental/jena-csv/src/test/java/com/hp/hpl/jena/propertytable/impl/GraphCSVTest.java
 Sun Jun 15 15:53:23 2014
@@ -29,6 +29,7 @@ import com.hp.hpl.jena.query.QuerySoluti
 import com.hp.hpl.jena.query.ResultSet;
 import com.hp.hpl.jena.rdf.model.Model;
 import com.hp.hpl.jena.rdf.model.ModelFactory;
+import com.hp.hpl.jena.util.PrintUtil;
 
 public class GraphCSVTest extends Assert {
        
@@ -37,10 +38,11 @@ public class GraphCSVTest extends Assert
                String file = "src/test/resources/test.csv";
                
                Model csv = ModelFactory.createModelForGraph(new 
GraphCSV(file));
-               assertEquals(6, csv.size());
+               assertEquals(12, csv.size());
 
                Query query = QueryFactory
-                               .create("PREFIX : 
<src/test/resources/test.csv#> SELECT ?townName ?pop {?x :Town ?townName ; 
:Population ?pop . FILTER(?pop > 500000)}");
+                               .create("PREFIX : 
<src/test/resources/test.csv#> SELECT ?townName ?pop {?x :Town ?townName ; 
:Population ?pop ; :Predicate%20With%20Space 'PredicateWithSpace2' . 
FILTER(?pop > 500000)}");
+               
                QueryExecution qexec = QueryExecutionFactory.create(query, csv);
                ResultSet results = qexec.execSelect();
                

Modified: jena/Experimental/jena-csv/src/test/resources/test.csv
URL: 
http://svn.apache.org/viewvc/jena/Experimental/jena-csv/src/test/resources/test.csv?rev=1602713&r1=1602712&r2=1602713&view=diff
==============================================================================
--- jena/Experimental/jena-csv/src/test/resources/test.csv (original)
+++ jena/Experimental/jena-csv/src/test/resources/test.csv Sun Jun 15 15:53:23 
2014
@@ -1,3 +1,3 @@
-Town,Population
-Southton,123000.0 
-Northville,654000 
+Town,Population,Predicate With Space,`~!@#$%^&*()-_=+[{]}|\;:'"<.>/?,1234
+Southton,123000.0,PredicateWithSpace1,NonURICharacters1,DigitalLocalName1
+Northville,654000,PredicateWithSpace2,NonURICharacters2,DigitalLocalName2


Reply via email to