Untitled

 avatar
unknown
c_cpp
2 years ago
1.8 kB
1
Indexable
#include <postgres.h>
#include <fmgr.h>
#include <miscadmin.h>
#include <utils/memutils.h>
#include <storage/shmem.h>
#include <unordered_map>

PG_MODULE_MAGIC;

typedef struct {
    char *name;
    int value;
} MyStruct;

static std::unordered_map<int, MyStruct*> *mystruct_map = nullptr;
static int mystruct_count = 0;

PG_FUNCTION_INFO_V1(create_foreign_table);

Datum create_foreign_table(PG_FUNCTION_ARGS)
{
    char *tablename = text_to_cstring(PG_GETARG_TEXT_P(0));
    MemoryContext oldcontext = CurrentMemoryContext;

    /* Allocate shared memory for mystruct map */
    char shmem_name[256];
    snprintf(shmem_name, 256, "mystruct_map");
    bool found;
    Size mapsize = sizeof(std::unordered_map<int, MyStruct*>);
    mystruct_map = (std::unordered_map<int, MyStruct*> *) ShmemInitStruct(shmem_name, mapsize, &found);
    if (!found) {
        new (mystruct_map) std::unordered_map<int, MyStruct*>;
    }

    /* Allocate shared memory for mystruct */
    snprintf(shmem_name, 256, "mystruct_%d", mystruct_count);
    Size structsize = sizeof(MyStruct);
    MyStruct *mystruct = (MyStruct *) ShmemInitStruct(shmem_name, structsize, &found);

    /* Initialize mystruct */
    mystruct->name = tablename;
    mystruct->value = mystruct_count;

    /* Add mystruct to the map */
    (*mystruct_map)[mystruct_count] = mystruct;
    mystruct_count++;

    PG_RETURN_VOID();
}

PG_FUNCTION_INFO_V1(get_mystruct_value);

Datum get_mystruct_value(PG_FUNCTION_ARGS)
{
    int index = PG_GETARG_INT32(0);
    if (mystruct_map == nullptr) {
        ereport(ERROR, (errmsg("mystruct_map is null")));
    }
    auto it = mystruct_map->find(index);
    if (it == mystruct_map->end()) {
        ereport(ERROR, (errmsg("mystruct not found")));
    }
    MyStruct *mystruct = it->second;
    PG_RETURN_INT32(mystruct->value);
}