Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: Please implement DefaultInMemoryGraphStore.remove() method #13

Open
bymihaj opened this issue May 24, 2019 · 3 comments

Comments

@bymihaj
Copy link

bymihaj commented May 24, 2019

I see that DefaultInMemoryGraphStore is deprecated. Maybe somebody could appoint me to easy use alternative ? In memory, without any databases.

@sipi
Copy link
Contributor

sipi commented May 24, 2019

Hi @bymihaj,
DefaultInMemoryGraphStore is not deprecated the annotation is @SuppressWarnings("deprecation"). By the way, this annotation should be more specific, not at the top level of the class.

Yes, we should implement the remove() method (like lot of other stuffs) however this is not trivial stuff because of the indexes. We have the following diff pending testing and validating (I have no idea if this code works or not). If you have the skills and the time, you can try it.

diff --git a/graal-core/src/main/java/fr/lirmm/graphik/graal/core/atomset/graph/AbstractTermVertex.java b/graal-core/src/main/java/fr/lirmm/graphik/graal/core/atomset/graph/AbstractTermVertex.java
index 55c926f34..064089550 100644
--- a/graal-core/src/main/java/fr/lirmm/graphik/graal/core/atomset/graph/AbstractTermVertex.java
+++ b/graal-core/src/main/java/fr/lirmm/graphik/graal/core/atomset/graph/AbstractTermVertex.java
@@ -127,6 +127,87 @@ abstract class AbstractTermVertex extends AbstractTerm implements TermVertex {
 		}
 		return res;
 	}
+	
+	@Override
+	public boolean removeNeighbor (AtomEdge a)
+	{
+		if (!containsNeighbor(a))
+			return false;
+		
+		Collection<Atom>[] map = this.index.get(a.getPredicate());
+		if (map == null) 
+		{
+			return false;
+		}
+
+		boolean res = false;
+		int i = -1;
+		for (Term t : a) {
+			++i;
+			if (this.equals(t)) {
+				Collection<Atom> collection = map[i];
+				if (collection == null) {
+					return false;
+				}
+				res = collection.remove(a) || res;
+				
+				if (collection.isEmpty())
+				{
+					map[i] = null;
+				}
+			}
+		}
+		
+		boolean toDeletePredicate = true;
+		for (Collection<Atom> m : this.index.get(a.getPredicate()))
+		{
+			if (m != null && !m.isEmpty())
+			{
+				toDeletePredicate = false;
+				break;
+			}
+		}
+		
+		if (toDeletePredicate)
+			this.index.remove(a.getPredicate());
+		
+		return res;		
+	}
+	
+	@Override
+	public boolean isEmptyNeighbor()
+	{
+		return this.index.isEmpty();
+	}
+	
+	@Override
+	public boolean containsNeighbor (AtomEdge a)
+	{
+		Collection<Atom>[] map = this.index.get(a.getPredicate());
+		if (map == null) 
+		{
+			return false;
+		}
+
+		int i = -1;
+		for (Term t : a) 
+		{
+			boolean res = false;
+			++i;
+			if (this.equals(t)) 
+			{
+				Collection<Atom> collection = map[i];
+				if (collection == null) 
+				{
+					return false;
+				}
+				
+				return collection.contains(a);
+				
+			}
+		}
+		return true;		
+	}
 
 	// /////////////////////////////////////////////////////////////////////////
 	// TERM METHODS
diff --git a/graal-core/src/main/java/fr/lirmm/graphik/graal/core/atomset/graph/DefaultInMemoryGraphStore.java b/graal-core/src/main/java/fr/lirmm/graphik/graal/core/atomset/graph/DefaultInMemoryGraphStore.java
index f9652fc9d..869a588ef 100644
--- a/graal-core/src/main/java/fr/lirmm/graphik/graal/core/atomset/graph/DefaultInMemoryGraphStore.java
+++ b/graal-core/src/main/java/fr/lirmm/graphik/graal/core/atomset/graph/DefaultInMemoryGraphStore.java
@@ -124,8 +124,66 @@ public class DefaultInMemoryGraphStore extends AbstractInMemoryAtomSet implement
 
 	@Override
 	public boolean remove(Atom atom) {
-		// TODO implement this method
-		throw new MethodNotImplementedError();
+		// On recrée l'AtomEdge à supprimer
+		List<TermVertex> atomTerms = new LinkedList<TermVertex>();
+		PredicateVertex atomPredicate;
+
+		for (Term t : atom.getTerms()) {
+			TermVertex tv = terms.get(t);
+			if (tv == null)
+				return false;
+			atomTerms.add(tv);
+		}
+		
+		atomPredicate = predicates.get(atom.getPredicate());
+		AtomEdge atomEdge = new AtomEdge(atomPredicate, atomTerms);
+		
+		if (!atomPredicate.containsNeighbor(atomEdge))
+			return false;
+
+		// On le supprime des voisins du prédicat
+		atomPredicate.removeNeighbor(atomEdge);
+		// On le supprime des voisins de chaque terme
+		for (TermVertex t : atomTerms) {
+			t.removeNeighbor(atomEdge);
+		}
+		
+		// Enfin on nettoie termsByPredicatePosition
+		int i = 0;
+		for (Term t : atom.getTerms())
+		{
+			// On vérifie, avant d'enlever le terme du prédicat, qu'aucun autre atome n'utilise le terme à la même position
+			boolean toDelete = true;
+			// On parcourt les  autres atomes utilisant le prédicat
+			for (Edge e : predicates.get(atomPredicate).getNeighbors())
+			{
+				if (((AtomEdge)e).indexOf(t) == i)
+				{
+					// On a trouvé un autre atome avec le même terme à la même position : on ne supprime pas le terme
+					toDelete = false;
+					break;
+				}
+			}
+			if (toDelete)
+				termsByPredicatePosition.get(atom.getPredicate())[i].remove(t);
+			++i;
+		}
+		
+		// Si le prédicat n'est plus utilisé, on le supprime
+		if (atomPredicate.isEmptyNeighbor())
+		{
+			predicates.remove(atomPredicate);
+		}
+		// On supprime les termes inutilisés
+		for (TermVertex t : atomTerms) {
+			if (t.isEmptyNeighbor())
+			{
+				terms.remove(t);
+			}
+		}
+		
+		--size;
+		return true;
 	}
 
 	@Override
@@ -253,6 +311,8 @@ public class DefaultInMemoryGraphStore extends AbstractInMemoryAtomSet implement
 	public void clear() {
 		this.terms.clear();
 		this.predicates.clear();
+		this.termsByPredicatePosition.clear();
+		this.size = 0;
 	}
 
 	@Override
diff --git a/graal-core/src/main/java/fr/lirmm/graphik/graal/core/atomset/graph/PredicateVertex.java b/graal-core/src/main/java/fr/lirmm/graphik/graal/core/atomset/graph/PredicateVertex.java
index a65561407..6e1b1755f 100644
--- a/graal-core/src/main/java/fr/lirmm/graphik/graal/core/atomset/graph/PredicateVertex.java
+++ b/graal-core/src/main/java/fr/lirmm/graphik/graal/core/atomset/graph/PredicateVertex.java
@@ -77,11 +77,29 @@ class PredicateVertex extends Predicate implements Vertex {
 	public Set<Edge> getNeighbors() {
 		return this.edges;
 	}
+	
+	@Override
+	public boolean isEmptyNeighbor()
+	{
+		return this.edges.isEmpty();
+	}
 
 	@Override
 	public boolean addNeighbor(AtomEdge a) {
 		return this.edges.add(a);
 	}
+	
+	@Override
+	public boolean removeNeighbor (AtomEdge a)
+	{
+		return this.edges.remove(a);
+	}
+	
+	@Override
+	public boolean containsNeighbor (AtomEdge a)
+	{
+		return this.edges.contains(a);
+	}
 
 	@Override
 	public boolean equals(Object o) {
diff --git a/graal-core/src/main/java/fr/lirmm/graphik/graal/core/atomset/graph/Vertex.java b/graal-core/src/main/java/fr/lirmm/graphik/graal/core/atomset/graph/Vertex.java
index 3e545c023..ed7e1cb8b 100644
--- a/graal-core/src/main/java/fr/lirmm/graphik/graal/core/atomset/graph/Vertex.java
+++ b/graal-core/src/main/java/fr/lirmm/graphik/graal/core/atomset/graph/Vertex.java
@@ -48,4 +48,10 @@ package fr.lirmm.graphik.graal.core.atomset.graph;
 interface Vertex {
 
 	boolean addNeighbor(AtomEdge a);
+	
+	boolean removeNeighbor (AtomEdge a);
+	
+	boolean containsNeighbor (AtomEdge a);
+	
+	boolean isEmptyNeighbor();
 }

@bymihaj
Copy link
Author

bymihaj commented May 24, 2019

In-memory instance of HSQL database is working stable. I investigated junit tests and should say - so hard for me.

@sipi
Copy link
Contributor

sipi commented May 25, 2019

Using SQLite can also be an option, or a RDF4JStore with a SailRepository if your data are Triples.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants