Skip to content

Commit 423ec45

Browse files
committed
Improve Vertex Label Retrieval
Rather than use the label_cache everytime, store the label name in a hash table, using the graph's oid and label's id as the key. Looks to have roughly a 10% performance improvement in debug mode.
1 parent 43010b5 commit 423ec45

File tree

1 file changed

+71
-1
lines changed

1 file changed

+71
-1
lines changed

src/backend/utils/adt/vertex.c

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "nodes/execnodes.h"
2828
#include "utils/array.h"
2929
#include "utils/fmgrprotos.h"
30+
#include "utils/hsearch.h"
3031
#include "utils/memutils.h"
3132
#include "utils/varlena.h"
3233

@@ -38,6 +39,8 @@
3839

3940
static void append_to_buffer(StringInfo buffer, const char *data, int len);
4041

42+
static HTAB *vertex_labels = NULL;
43+
4144
/*
4245
* I/O routines for vertex type
4346
*/
@@ -633,18 +636,85 @@ append_to_buffer(StringInfo buffer, const char *data, int len) {
633636
memcpy(buffer->data + offset, data, len);
634637
}
635638

639+
typedef struct label_key {
640+
Oid graph_oid;
641+
int32 label_id;
642+
} label_key;
643+
644+
typedef struct label_entry {
645+
label_key key;
646+
char *label;
647+
} label_entry;
648+
649+
static uint32 label_key_hash(const void *key, Size keysize) {
650+
label_key *lkey = key;
651+
return lkey->graph_oid + lkey->label_id;
652+
}
653+
654+
static int label_key_cmp(const void *key1, const void *key2, size_t len) {
655+
label_key *lkey1 = key1;
656+
label_key *lkey2 = key2;
657+
658+
if (lkey1->graph_oid > lkey2->graph_oid) {
659+
return 1;
660+
} else if (lkey1->graph_oid > lkey2->graph_oid) {
661+
return -1;
662+
}
663+
664+
if (lkey1->label_id > lkey2->label_id) {
665+
return 1;
666+
} else if (lkey1->label_id < lkey2->label_id) {
667+
return -1;
668+
}
669+
670+
return 0;
671+
}
672+
673+
674+
HASHCTL labels_info = {
675+
.keysize = sizeof(label_key),
676+
.entrysize = sizeof(label_entry),
677+
.hash = label_key_hash,
678+
.match = label_key_cmp,
679+
.keycopy = memcpy
680+
};
681+
636682
char *
637683
extract_vertex_label(vertex *v) {
638684
graphid id = EXTRACT_VERTEX_ID(v);
639685
int32 label_id = get_graphid_label_id(id);
640686

641687
Oid graph_oid = EXTRACT_VERTEX_GRAPH_OID(v);
688+
label_key key = { .graph_oid=graph_oid, .label_id=label_id};
689+
690+
if (!vertex_labels) {
691+
vertex_labels = hash_create("vertex label hash", 1000, &labels_info, HASH_ELEM | HASH_FUNCTION | HASH_COMPARE | HASH_KEYCOPY);
692+
}
693+
694+
bool found;
695+
label_entry *lentry = hash_search(vertex_labels, &key, HASH_ENTER, &found);
696+
697+
if (found) {
698+
return lentry->label;
699+
}
642700

643701
label_cache_data *cache_data = search_label_graph_oid_cache(graph_oid, label_id);
644702
char *label = NameStr(cache_data->name);
645703

646-
if (IS_AG_DEFAULT_LABEL(label))
704+
if (IS_AG_DEFAULT_LABEL(label)) {
705+
lentry->label = "";
647706
return "";
707+
}
708+
709+
MemoryContext oldcontext = MemoryContextSwitchTo(TopMemoryContext);
710+
711+
int len = strlen(label) + 1;
712+
char *l = palloc0(len * sizeof(char));
713+
memcpy(l, label, len);
714+
715+
//label_entry *e = hash_search(vertex_labels, &key, HASH_ENTER, &found);
716+
lentry->label = l;
717+
MemoryContextSwitchTo(oldcontext);
648718

649719
return label;
650720
}

0 commit comments

Comments
 (0)