|
27 | 27 | #include "nodes/execnodes.h"
|
28 | 28 | #include "utils/array.h"
|
29 | 29 | #include "utils/fmgrprotos.h"
|
| 30 | +#include "utils/hsearch.h" |
30 | 31 | #include "utils/memutils.h"
|
31 | 32 | #include "utils/varlena.h"
|
32 | 33 |
|
|
38 | 39 |
|
39 | 40 | static void append_to_buffer(StringInfo buffer, const char *data, int len);
|
40 | 41 |
|
| 42 | +static HTAB *vertex_labels = NULL; |
| 43 | + |
41 | 44 | /*
|
42 | 45 | * I/O routines for vertex type
|
43 | 46 | */
|
@@ -633,18 +636,85 @@ append_to_buffer(StringInfo buffer, const char *data, int len) {
|
633 | 636 | memcpy(buffer->data + offset, data, len);
|
634 | 637 | }
|
635 | 638 |
|
| 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 | + |
636 | 682 | char *
|
637 | 683 | extract_vertex_label(vertex *v) {
|
638 | 684 | graphid id = EXTRACT_VERTEX_ID(v);
|
639 | 685 | int32 label_id = get_graphid_label_id(id);
|
640 | 686 |
|
641 | 687 | 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 | + } |
642 | 700 |
|
643 | 701 | label_cache_data *cache_data = search_label_graph_oid_cache(graph_oid, label_id);
|
644 | 702 | char *label = NameStr(cache_data->name);
|
645 | 703 |
|
646 |
| - if (IS_AG_DEFAULT_LABEL(label)) |
| 704 | + if (IS_AG_DEFAULT_LABEL(label)) { |
| 705 | + lentry->label = ""; |
647 | 706 | 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); |
648 | 718 |
|
649 | 719 | return label;
|
650 | 720 | }
|
|
0 commit comments