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

dehowef pushed a commit to branch PG13
in repository https://gitbox.apache.org/repos/asf/age.git


The following commit(s) were added to refs/heads/PG13 by this push:
     new a87d83ae Minor VLE and agtype_eq/ne performance updates (#1808) (#1819)
a87d83ae is described below

commit a87d83ae798f78ed11f55b270e33d3cc060365e8
Author: John Gemignani <[email protected]>
AuthorDate: Tue Apr 30 19:41:50 2024 -0700

    Minor VLE and agtype_eq/ne performance updates (#1808) (#1819)
    
    Integrated datum_image_hash and datum_image_eq to the logic for the
    VLE edge property datum match.
    
    Additionally, both were added to agtype_eq and agtype_ne.
    
    The hope is that, for large datums, these routines will improve
    performance.
    
    No impact to regression tests.
    
    Modified the following files to point to datum_image_hash which was
    previously ported down to PG13 from PG14 -
    
        modified:   src/backend/utils/adt/age_vle.c
        modified:   src/backend/utils/adt/agtype_ops.c
---
 src/backend/utils/adt/age_vle.c    | 63 ++++++++++++++++++++++++++++++++------
 src/backend/utils/adt/agtype_ops.c | 40 ++++++++++++++++++++----
 src/include/catalog/ag_label.h     |  1 -
 3 files changed, 88 insertions(+), 16 deletions(-)

diff --git a/src/backend/utils/adt/age_vle.c b/src/backend/utils/adt/age_vle.c
index 6e3464ad..8fcd5d5b 100644
--- a/src/backend/utils/adt/age_vle.c
+++ b/src/backend/utils/adt/age_vle.c
@@ -21,11 +21,14 @@
 
 #include "common/hashfn.h"
 #include "funcapi.h"
+#include "utils/datum.h"
 #include "utils/lsyscache.h"
 
-#include "utils/age_vle.h"
 #include "catalog/ag_graph.h"
+#include "catalog/ag_label.h"
+#include "executor/cypher_utils.h"
 #include "nodes/cypher_nodes.h"
+#include "utils/age_vle.h"
 
 /* defines */
 #define GET_GRAPHID_ARRAY_FROM_CONTAINER(vpc) \
@@ -68,7 +71,10 @@ typedef struct VLE_local_context
     graphid vsid;                  /* starting vertex id */
     graphid veid;                  /* ending vertex id */
     char *edge_label_name;         /* edge label name for match */
+    Oid edge_label_name_oid;       /* edge label name oid for match */
     agtype *edge_property_constraint; /* edge property constraint as agtype */
+    Datum edge_property_constraint_datum; /* edge property constraint as Datum 
*/
+    uint32 edge_property_constraint_hash; /* edge property constraint hash */
     int64 lidx;                    /* lower (start) bound index */
     int64 uidx;                    /* upper (end) bound index */
     bool uidx_infinite;            /* flag if the upper bound is omitted */
@@ -328,7 +334,7 @@ static bool is_an_edge_match(VLE_local_context *vlelctx, 
edge_entry *ee)
     agtype_container *agtc_edge_property_constraint = NULL;
     agtype_iterator *constraint_it = NULL;
     agtype_iterator *property_it = NULL;
-    char *edge_label_name = NULL;
+    Oid edge_label_name_oid = InvalidOid;
     int num_edge_property_constraints = 0;
     int num_edge_properties = 0;
 
@@ -340,13 +346,25 @@ static bool is_an_edge_match(VLE_local_context *vlelctx, 
edge_entry *ee)
      * We don't care about extra unmatched properties. If there aren't any edge
      * constraints, then the edge passes by default.
      */
-    if (vlelctx->edge_label_name == NULL && num_edge_property_constraints == 0)
+    if (vlelctx->edge_label_name_oid == InvalidOid &&
+        num_edge_property_constraints == 0)
     {
         return true;
     }
 
-    /* get the edge label name from the oid */
-    edge_label_name = get_rel_name(get_edge_entry_label_table_oid(ee));
+    /* get the edge label oid */
+    edge_label_name_oid = get_edge_entry_label_table_oid(ee);
+
+    /*
+     * Check for a label constraint. Remember, if the constraint label oid is
+     * InvalidOid, there isn't one. If there is one, they need to match.
+     */
+    if (vlelctx->edge_label_name_oid != InvalidOid &&
+        vlelctx->edge_label_name_oid != edge_label_name_oid)
+    {
+        return false;
+    }
+
     /* get our edge's properties */
     edge_property = DATUM_GET_AGTYPE_P(get_edge_entry_properties(ee));
     /* get the containers */
@@ -366,11 +384,26 @@ static bool is_an_edge_match(VLE_local_context *vlelctx, 
edge_entry *ee)
     }
 
     /*
-     * Check for a label constraint. If the label name is NULL, there isn't 
one.
+     * If the number of constraints are the same as the number of properties,
+     * then the datums would be the same if they match.
      */
-    if (vlelctx->edge_label_name != NULL &&
-        strcmp(vlelctx->edge_label_name, edge_label_name) != 0)
+    if (num_edge_property_constraints == num_edge_properties)
     {
+        Datum edge_props = get_edge_entry_properties(ee);
+        uint32 edge_props_hash = datum_image_hash(edge_props, false, -1);
+
+        /* check the hash first */
+        if (vlelctx->edge_property_constraint_hash == edge_props_hash)
+        {
+            /* if the hashes match, check the datum images */
+            if (datum_image_eq(vlelctx->edge_property_constraint_datum,
+                               edge_props, false, -1))
+            {
+                return true;
+            }
+        }
+
+        /* if we got here they aren't the same */
         return false;
     }
 
@@ -491,6 +524,8 @@ static VLE_local_context 
*build_local_vle_context(FunctionCallInfo fcinfo,
     VLE_local_context *vlelctx = NULL;
     agtype_value *agtv_temp = NULL;
     agtype_value *agtv_object = NULL;
+    agtype *agt_edge_property_constraint = NULL;
+    Datum d_edge_property_constraint = 0;
     char *graph_name = NULL;
     Oid graph_oid = InvalidOid;
     int64 vle_grammar_node_id = 0;
@@ -713,8 +748,14 @@ static VLE_local_context 
*build_local_vle_context(FunctionCallInfo fcinfo,
 
     /* get the edge prototype's property conditions */
     agtv_object = GET_AGTYPE_VALUE_OBJECT_VALUE(agtv_temp, "properties");
+    agt_edge_property_constraint = agtype_value_to_agtype(agtv_object);
+
     /* store the properties as an agtype */
-    vlelctx->edge_property_constraint = agtype_value_to_agtype(agtv_object);
+    vlelctx->edge_property_constraint = agt_edge_property_constraint;
+
+    d_edge_property_constraint = 
AGTYPE_P_GET_DATUM(agt_edge_property_constraint);
+    vlelctx->edge_property_constraint_datum = d_edge_property_constraint;
+    vlelctx->edge_property_constraint_hash = 
datum_image_hash(d_edge_property_constraint, false, -1);
 
     /* get the edge prototype's label name */
     agtv_temp = GET_AGTYPE_VALUE_OBJECT_VALUE(agtv_temp, "label");
@@ -723,10 +764,14 @@ static VLE_local_context 
*build_local_vle_context(FunctionCallInfo fcinfo,
     {
         vlelctx->edge_label_name = pnstrdup(agtv_temp->val.string.val,
                                             agtv_temp->val.string.len);
+
+        vlelctx->edge_label_name_oid = 
get_label_relation(vlelctx->edge_label_name,
+                                                          graph_oid);
     }
     else
     {
         vlelctx->edge_label_name = NULL;
+        vlelctx->edge_label_name_oid = InvalidOid;
     }
 
     /* get the left range index */
diff --git a/src/backend/utils/adt/agtype_ops.c 
b/src/backend/utils/adt/agtype_ops.c
index d2b6430f..6c97ee7f 100644
--- a/src/backend/utils/adt/agtype_ops.c
+++ b/src/backend/utils/adt/agtype_ops.c
@@ -26,7 +26,9 @@
 #include <math.h>
 #include <limits.h>
 
+#include "executor/cypher_utils.h"
 #include "utils/agtype.h"
+#include "utils/datum.h"
 #include "utils/builtins.h"
 
 static agtype *agtype_concat_impl(agtype *agt1, agtype *agt2);
@@ -1009,9 +1011,22 @@ PG_FUNCTION_INFO_V1(agtype_eq);
 
 Datum agtype_eq(PG_FUNCTION_ARGS)
 {
-    agtype *agtype_lhs = AG_GET_ARG_AGTYPE_P(0);
-    agtype *agtype_rhs = AG_GET_ARG_AGTYPE_P(1);
-    bool result;
+    Datum lhs = PG_GETARG_DATUM(0);
+    Datum rhs = PG_GETARG_DATUM(1);
+    agtype *agtype_lhs = NULL;
+    agtype *agtype_rhs = NULL;
+    uint32 hash_lhs = datum_image_hash(lhs, false, -1);
+    uint32 hash_rhs = datum_image_hash(rhs, false, -1);
+    bool result = false;
+
+    if (hash_lhs == hash_rhs &&
+        datum_image_eq(lhs, rhs, false, -1))
+    {
+        PG_RETURN_BOOL(true);
+    }
+
+    agtype_lhs = DATUM_GET_AGTYPE_P(lhs);
+    agtype_rhs = DATUM_GET_AGTYPE_P(rhs);
 
     result = (compare_agtype_containers_orderability(&agtype_lhs->root,
                                                      &agtype_rhs->root) == 0);
@@ -1048,9 +1063,22 @@ PG_FUNCTION_INFO_V1(agtype_ne);
 
 Datum agtype_ne(PG_FUNCTION_ARGS)
 {
-    agtype *agtype_lhs = AG_GET_ARG_AGTYPE_P(0);
-    agtype *agtype_rhs = AG_GET_ARG_AGTYPE_P(1);
-    bool result = true;
+    Datum lhs = PG_GETARG_DATUM(0);
+    Datum rhs = PG_GETARG_DATUM(1);
+    uint32 hash_lhs = datum_image_hash(lhs, false, -1);
+    uint32 hash_rhs = datum_image_hash(rhs, false, -1);
+    agtype *agtype_lhs = NULL;
+    agtype *agtype_rhs = NULL;
+    bool result = false;
+
+    if (hash_lhs == hash_rhs &&
+        datum_image_eq(lhs, rhs, false, -1))
+    {
+        PG_RETURN_BOOL(false);
+    }
+
+    agtype_lhs = DATUM_GET_AGTYPE_P(lhs);
+    agtype_rhs = DATUM_GET_AGTYPE_P(rhs);
 
     result = (compare_agtype_containers_orderability(&agtype_lhs->root,
                                                      &agtype_rhs->root) != 0);
diff --git a/src/include/catalog/ag_label.h b/src/include/catalog/ag_label.h
index 46ea9bc7..6c5e0333 100644
--- a/src/include/catalog/ag_label.h
+++ b/src/include/catalog/ag_label.h
@@ -72,7 +72,6 @@ void delete_label(Oid relation);
 int32 get_label_id(const char *label_name, Oid graph_oid);
 Oid get_label_relation(const char *label_name, Oid graph_oid);
 char *get_label_relation_name(const char *label_name, Oid graph_oid);
-Oid get_label_oid(const char *label_name, Oid label_graph);
 char get_label_kind(const char *label_name, Oid label_graph);
 
 bool label_id_exists(Oid graph_oid, int32 label_id);

Reply via email to