You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by nb...@apache.org on 2020/10/30 11:56:53 UTC

[atlas] branch master updated: ATLAS-4008: Cache getGuid and getStatus in GraphTransactionInterceptor

This is an automated email from the ASF dual-hosted git repository.

nbonte pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/atlas.git


The following commit(s) were added to refs/heads/master by this push:
     new 7c68048  ATLAS-4008: Cache getGuid and getStatus in GraphTransactionInterceptor
7c68048 is described below

commit 7c68048fcc314d83100c7a5fc0a5b8294f62e2cd
Author: Nikhil Bonte <ni...@freestoneinfotech.com>
AuthorDate: Wed Oct 28 12:06:10 2020 +0530

    ATLAS-4008: Cache getGuid and getStatus in GraphTransactionInterceptor
    
    Signed-off-by: Nikhil Bonte <nb...@apache.org>
---
 .../apache/atlas/GraphTransactionInterceptor.java  | 96 +++++++++++++++++++++-
 .../apache/atlas/repository/graph/GraphHelper.java | 41 ++++++++-
 .../repository/store/graph/v1/DeleteHandlerV1.java | 22 ++++-
 .../store/graph/v2/AtlasComplexAttributesTest.java |  2 +
 .../store/graph/v2/AtlasEntityStoreV2Test.java     |  4 +
 5 files changed, 157 insertions(+), 8 deletions(-)

diff --git a/repository/src/main/java/org/apache/atlas/GraphTransactionInterceptor.java b/repository/src/main/java/org/apache/atlas/GraphTransactionInterceptor.java
index 57e454a..86b369f 100644
--- a/repository/src/main/java/org/apache/atlas/GraphTransactionInterceptor.java
+++ b/repository/src/main/java/org/apache/atlas/GraphTransactionInterceptor.java
@@ -23,6 +23,7 @@ import org.aopalliance.intercept.MethodInvocation;
 import org.apache.atlas.annotation.GraphTransaction;
 import org.apache.atlas.exception.AtlasBaseException;
 import org.apache.atlas.exception.NotFoundException;
+import org.apache.atlas.model.instance.AtlasEntity;
 import org.apache.atlas.repository.graphdb.AtlasGraph;
 import org.apache.atlas.repository.graphdb.AtlasVertex;
 import org.apache.atlas.utils.AtlasPerfMetrics.MetricRecorder;
@@ -54,6 +55,30 @@ public class GraphTransactionInterceptor implements MethodInterceptor {
 
     private final AtlasGraph graph;
 
+    private static final ThreadLocal<Map<Object, String>> vertexGuidCache =
+            new ThreadLocal<Map<Object, String>>() {
+                @Override
+                public Map<Object, String> initialValue() {
+                    return new HashMap<Object, String>();
+                }
+            };
+
+    private static final ThreadLocal<Map<Object, AtlasEntity.Status>> vertexStateCache =
+            new ThreadLocal<Map<Object, AtlasEntity.Status>>() {
+                @Override
+                public Map<Object, AtlasEntity.Status> initialValue() {
+                    return new HashMap<Object, AtlasEntity.Status>();
+                }
+            };
+
+    private static final ThreadLocal<Map<Object, AtlasEntity.Status>> edgeStateCache =
+            new ThreadLocal<Map<Object, AtlasEntity.Status>>() {
+                @Override
+                public Map<Object, AtlasEntity.Status> initialValue() {
+                    return new HashMap<Object, AtlasEntity.Status>();
+                }
+            };
+
     @Inject
     public GraphTransactionInterceptor(AtlasGraph graph) {
         this.graph = graph;
@@ -117,7 +142,7 @@ public class GraphTransactionInterceptor implements MethodInterceptor {
                 // Reset the boolean flags
                 isTxnOpen.set(Boolean.FALSE);
                 innerFailure.set(Boolean.FALSE);
-                guidVertexCache.get().clear();
+                clearCache();
 
                 List<PostTransactionHook> trxHooks = postTransactionHooks.get();
 
@@ -201,6 +226,9 @@ public class GraphTransactionInterceptor implements MethodInterceptor {
 
     public static void clearCache() {
         guidVertexCache.get().clear();
+        vertexGuidCache.get().clear();
+        vertexStateCache.get().clear();
+        edgeStateCache.get().clear();
     }
 
     boolean logException(Throwable t) {
@@ -214,6 +242,72 @@ public class GraphTransactionInterceptor implements MethodInterceptor {
         }
     }
 
+    public static void addToVertexGuidCache(Object vertexId, String guid) {
+
+        if (guid == null) {
+            removeFromVertexGuidCache(vertexId);
+        } else {
+            Map<Object, String> cache = vertexGuidCache.get();
+            cache.put(vertexId, guid);
+        }
+    }
+
+    public static void removeFromVertexGuidCache(Object vertexId) {
+        Map<Object, String> cache = vertexGuidCache.get();
+
+        cache.remove(vertexId);
+    }
+
+    public static String getVertexGuidFromCache(Object vertexId) {
+        Map<Object, String> cache = vertexGuidCache.get();
+
+        return cache.get(vertexId);
+    }
+
+    public static void addToVertexStateCache(Object vertexId, AtlasEntity.Status status) {
+
+        if (status == null) {
+            removeFromVertexStateCache(vertexId);
+        } else {
+            Map<Object, AtlasEntity.Status> cache = vertexStateCache.get();
+            cache.put(vertexId, status);
+        }
+    }
+
+    public static void removeFromVertexStateCache(Object vertexId) {
+        Map<Object, AtlasEntity.Status> cache = vertexStateCache.get();
+
+        cache.remove(vertexId);
+    }
+
+    public static AtlasEntity.Status getVertexStateFromCache(Object vertexId) {
+        Map<Object, AtlasEntity.Status> cache = vertexStateCache.get();
+
+        return cache.get(vertexId);
+    }
+
+    public static void addToEdgeStateCache(Object edgeId, AtlasEntity.Status status) {
+
+        if (status == null) {
+            removeFromEdgeStateCache(edgeId);
+        } else {
+            Map<Object, AtlasEntity.Status> cache = edgeStateCache.get();
+            cache.put(edgeId, status);
+        }
+    }
+
+    public static void removeFromEdgeStateCache(Object edgeId) {
+        Map<Object, AtlasEntity.Status> cache = edgeStateCache.get();
+
+        cache.remove(edgeId);
+    }
+
+    public static AtlasEntity.Status getEdgeStateFromCache(Object edgeId) {
+        Map<Object, AtlasEntity.Status> cache = edgeStateCache.get();
+
+        return cache.get(edgeId);
+    }
+
     public static abstract class PostTransactionHook {
         protected PostTransactionHook() {
             List<PostTransactionHook> trxHooks = postTransactionHooks.get();
diff --git a/repository/src/main/java/org/apache/atlas/repository/graph/GraphHelper.java b/repository/src/main/java/org/apache/atlas/repository/graph/GraphHelper.java
index ca46d0f..ff7fd15 100755
--- a/repository/src/main/java/org/apache/atlas/repository/graph/GraphHelper.java
+++ b/repository/src/main/java/org/apache/atlas/repository/graph/GraphHelper.java
@@ -24,6 +24,7 @@ import com.google.common.collect.HashBiMap;
 import org.apache.atlas.ApplicationProperties;
 import org.apache.atlas.AtlasErrorCode;
 import org.apache.atlas.AtlasException;
+import org.apache.atlas.GraphTransactionInterceptor;
 import org.apache.atlas.RequestContext;
 import org.apache.atlas.exception.AtlasBaseException;
 import org.apache.atlas.model.instance.AtlasEntity;
@@ -815,8 +816,17 @@ public final class GraphHelper {
         return element.getProperty(Constants.RELATIONSHIP_GUID_PROPERTY_KEY, String.class);
     }
 
-    public static String getGuid(AtlasElement element) {
-        return element.<String>getProperty(Constants.GUID_PROPERTY_KEY, String.class);
+    public static String getGuid(AtlasVertex vertex) {
+        Object vertexId = vertex.getId();
+        String ret = GraphTransactionInterceptor.getVertexGuidFromCache(vertexId);
+
+        if (ret == null) {
+            ret = vertex.<String>getProperty(Constants.GUID_PROPERTY_KEY, String.class);
+
+            GraphTransactionInterceptor.addToVertexGuidCache(vertexId, ret);
+        }
+
+        return ret;
     }
 
     public static String getHomeId(AtlasElement element) {
@@ -870,10 +880,33 @@ public final class GraphHelper {
         return element.getProperty(STATE_PROPERTY_KEY, String.class);
     }
 
-    public static Status getStatus(AtlasElement element) {
-        return (getState(element) == Id.EntityState.DELETED) ? Status.DELETED : Status.ACTIVE;
+    public static Status getStatus(AtlasVertex vertex) {
+        Object vertexId = vertex.getId();
+        Status ret = GraphTransactionInterceptor.getVertexStateFromCache(vertexId);
+
+        if (ret == null) {
+            ret = (getState(vertex) == Id.EntityState.DELETED) ? Status.DELETED : Status.ACTIVE;
+
+            GraphTransactionInterceptor.addToVertexStateCache(vertexId, ret);
+        }
+
+        return ret;
+    }
+
+    public static Status getStatus(AtlasEdge edge) {
+        Object edgeId = edge.getId();
+        Status ret = GraphTransactionInterceptor.getEdgeStateFromCache(edgeId);
+
+        if (ret == null) {
+            ret = (getState(edge) == Id.EntityState.DELETED) ? Status.DELETED : Status.ACTIVE;
+
+            GraphTransactionInterceptor.addToEdgeStateCache(edgeId, ret);
+        }
+
+        return ret;
     }
 
+
     public static AtlasRelationship.Status getEdgeStatus(AtlasElement element) {
         return (getState(element) == Id.EntityState.DELETED) ? AtlasRelationship.Status.DELETED : AtlasRelationship.Status.ACTIVE;
     }
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/DeleteHandlerV1.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/DeleteHandlerV1.java
index 9360dd3..7b2e2d3 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/DeleteHandlerV1.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/DeleteHandlerV1.java
@@ -961,10 +961,13 @@ public abstract class DeleteHandlerV1 {
                     deleteRelationship(edge);
                 } else {
                     AtlasVertex    outVertex = edge.getOutVertex();
-                    AtlasVertex    inVertex  = edge.getInVertex();
-                    AtlasAttribute attribute = getAttributeForEdge(edge.getLabel());
 
-                    deleteEdgeBetweenVertices(outVertex, inVertex, attribute);
+                    if (!isDeletedEntity(outVertex)) {
+                        AtlasVertex inVertex = edge.getInVertex();
+                        AtlasAttribute attribute = getAttributeForEdge(edge.getLabel());
+
+                        deleteEdgeBetweenVertices(outVertex, inVertex, attribute);
+                    }
                 }
             }
         }
@@ -972,6 +975,19 @@ public abstract class DeleteHandlerV1 {
         _deleteVertex(instanceVertex, force);
     }
 
+    private boolean isDeletedEntity(AtlasVertex entityVertex) {
+        boolean            ret      = false;
+        String             outGuid  = GraphHelper.getGuid(entityVertex);
+        AtlasEntity.Status outState = GraphHelper.getStatus(entityVertex);
+
+        //If the reference vertex is marked for deletion, skip updating the reference
+        if (outState == AtlasEntity.Status.DELETED || (outGuid != null && RequestContext.get().isDeletedEntity(outGuid))) {
+            ret = true;
+        }
+
+        return ret;
+    }
+
     public void deleteClassificationVertex(AtlasVertex classificationVertex, boolean force) {
         if (LOG.isDebugEnabled()) {
             LOG.debug("Deleting classification vertex", string(classificationVertex));
diff --git a/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasComplexAttributesTest.java b/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasComplexAttributesTest.java
index ad5fa92..b482365 100644
--- a/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasComplexAttributesTest.java
+++ b/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasComplexAttributesTest.java
@@ -17,6 +17,7 @@
  */
 package org.apache.atlas.repository.store.graph.v2;
 
+import org.apache.atlas.GraphTransactionInterceptor;
 import org.apache.atlas.TestModules;
 import org.apache.atlas.TestUtilsV2;
 import org.apache.atlas.model.instance.AtlasEntity;
@@ -645,6 +646,7 @@ public class AtlasComplexAttributesTest extends AtlasEntityTestBase {
 
         AtlasEntityHeader entityDeleted = response.getFirstDeletedEntityByTypeName(ENTITY_TYPE_WITH_COMPLEX_COLLECTION_ATTR);
 
+        GraphTransactionInterceptor.clearCache();
         AtlasEntityWithExtInfo deletedEntityWithExtInfo = entityStore.getById(entityDeleted.getGuid());
         AtlasVertex            deletedEntityVertex      = AtlasGraphUtilsV2.findByGuid(entityDeleted.getGuid());
         Iterator<AtlasEdge>    edges                    = deletedEntityVertex.getEdges(AtlasEdgeDirection.OUT).iterator();
diff --git a/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2Test.java b/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2Test.java
index b9cbef1..c9f4912 100644
--- a/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2Test.java
+++ b/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2Test.java
@@ -19,6 +19,7 @@ package org.apache.atlas.repository.store.graph.v2;
 
 import com.google.common.collect.ImmutableSet;
 import org.apache.atlas.AtlasErrorCode;
+import org.apache.atlas.GraphTransactionInterceptor;
 import org.apache.atlas.RequestContext;
 import org.apache.atlas.TestModules;
 import org.apache.atlas.TestUtilsV2;
@@ -859,6 +860,7 @@ public class AtlasEntityStoreV2Test extends AtlasEntityTestBase {
 
         entityStore.createOrUpdate(new AtlasEntityStream(dbEntity), false);
         entityStore.createOrUpdate(new AtlasEntityStream(db2Entity), false);
+        GraphTransactionInterceptor.clearCache();
 
         final AtlasEntity tableEntity = TestUtilsV2.createTableEntity(dbEntity);
 
@@ -873,6 +875,8 @@ public class AtlasEntityStoreV2Test extends AtlasEntityTestBase {
         createdTblEntity.setAttribute("databaseComposite", null);
 
         final EntityMutationResponse tblUpdateResponse = entityStore.createOrUpdate(new AtlasEntityStream(createdTblEntity), true);
+        GraphTransactionInterceptor.clearCache();
+
         final AtlasEntityHeader      updatedTblHeader  = tblUpdateResponse.getFirstEntityPartialUpdated();
         final AtlasEntity            updatedTblEntity  = getEntityFromStore(updatedTblHeader);
         final AtlasEntity            deletedDb2Entity  = getEntityFromStore(db2Entity.getGuid());