PostgreSQL/開発

概要

定義

マクロ

MemoryContextAllocExtendedのフラグ

マクロ名説明
MCXT_ALLOC_HUGE1GB以上のアロケーションを許容
MCXT_ALLOC_NO_OOMOutOfMemoryでもエラーにしない
MCXT_ALLOC_ZERO0クリアする

palloc0fast

// 引数1:アロケーションサイズ
palloc0fast(sz)

 参考  palloc0fast - on doxygen.postgresql.org

列挙型

構造体

MemoryContextCallback

番号データ型フィールド説明
1MemoryContextCallbackFunctionfuncコールバック関数
2void*argコールバック関数に渡される引数
3struct MemoryContextCallbacknextコールバック関数リストの次ノード。
コールバック関数はリスト構造で管理されており複数のコールバック関数を登録できる。

MemoryContext

MemoryContextDataポインタの別名

typedef struct MemoryContextData *MemoryContext;

 参考  struct MemoryContextData - on doxygen.postgresql.org

関数

MemoryContextAlloc

// 引数1:アロケーション対象のコンテキスト
// 引数2:割当てサイズ(byte)
// 戻り値:メモリチャンクのポインタ
extern void *MemoryContextAlloc(MemoryContext context, Size size);

 参考 

 サンプル 

void memory_sample()
{
    // 専用のコンテキストを作成
    MemoryContext context = AllocSetContextCreate(CurrentMemoryContext,
                                                   "mycontext",
                                                   0,
                                                   8 * 1024,
                                                   8 * 1024);
    MemoryContext oldcontext = NULL;

    // カレントコンテキストのスイッチ
    oldcontext = MemoryContextSwitchTo(context);

    // メモリチャンクが返される
    MyExtensionOptions *opt = (MyExtensionOptions*) MemoryContextAlloc(context,
                                                                       sizeof(MyExtensionOptions));
    // pallocは,内部でCurrentMemoryContextを使う
    // MyExtensionOptions *opt  = (MyExtensionOptions*)palloc(sizeof(MyExtensionOptions));
    opt->optcontext = ForeignTableRelationId;
    opt->optname = pstrdup("option1");

    MemoryContextSwitchTo(oldcontext);
    MemoryContextDelete(context);
}

MemoryContextAllocZero

// 引数1:アロケーション対象のコンテキスト
// 引数2:アロケーションサイズ(byte)
// 戻り値:メモリチャンクのポインタ
extern void *MemoryContextAllocZero(MemoryContext context, Size size);

MemoryContextAllocZeroAligned

// 引数1:アロケーション対象のコンテキスト
// 引数2:アロケーションサイズ(byte)
// 戻り値:メモリチャンクのポインタ
extern void *MemoryContextAllocZeroAligned(MemoryContext context, Size size);

MemoryContextAllocExtended

// 引数1:アロケーション対象のコンテキスト
// 引数2:アロケーションサイズ(byte)
// 引数3:メモリアロケーション動作を決めるフラグ
// 戻り値:メモリチャンクのポインタ
extern void *MemoryContextAllocExtended(MemoryContext context, Size size, int flags);

 参考  MemoryContextAllocExtended() - on doxygen.postgresql.org

 サンプル 

typedef struct MyExtensionOptions {
    const char *optname;
    Oid optcontext;
} MyExtensionOptions;

void memory_sample()
{
    MemoryContext context = AllocSetContextCreate(CurrentMemoryContext,
                                                   "mycontext",
                                                   0,
                                                   8 * 1024,
                                                   8 * 1024);
    MemoryContext oldcontext = NULL;

    oldcontext = MemoryContextSwitchTo(context);

    // 0クリア and メモリ確保失敗時にエラー報告
    MyExtensionOptions *opt = (MyExtensionOptions*) MemoryContextAllocExtended(context,
                                                                               sizeof(MyExtensionOptions),
                                                                               MCXT_ALLOC_ZERO | MCXT_ALLOC_NO_OOM);

    opt->optcontext = ForeignTableRelationId;
    opt->optname = pstrdup("option1");

    MemoryContextSwitchTo(oldcontext);
    MemoryContextDelete(context);
}

palloc

// 引数1:アロケーションサイズ(byte)
// 戻り値:メモリチャンクのポインタ
extern void *palloc(Size size);

 参考  palloc() - on doxygen.postgresql.org

 サンプル 

MyExtensionOptions *opt  = (MyExtensionOptions*)palloc(sizeof(MyExtensionOptions));
// 以下と同様である
// MyExtensionOptions  * opt = MemoryContextAlloc(CurrentMemoryContext, sizeof(MyExtensionOptions));

palloc0

// 引数1:アロケーションサイズ(byte)
// 戻り値:メモリチャンクのポインタ
extern void *palloc0(Size size);

palloc_extended

// 引数1:アロケーションサイズ(byte)
// 引数2:メモリアロケーション動作を決めるフラグ
// 戻り値:メモリチャンクのポインタ
extern void *palloc_extended(Size size, int flags);

repalloc

// 引数1:メモリチャンクのポインタ
// 引数2:再割り当てするサイズ(byte)
// 戻り値:新しいメモリチャンクのポインタ
extern void *repalloc(void *pointer, Size size);

 参考  AllocSetRealloc() - on doxygen.postgresql.org

 サンプル 

char *optname = palloc(1 << 4);
strcpy(optname, "hello world");
char *newoptname = repalloc(optname, 1 << 5);
strcpy(newoptname, "hello world, hello postgres");

pfree

// 引数1:メモリチャンクのポインタ
extern void pfree(void *pointer);

 参考  AllocSetFree() - on doxygen.postgresql.org

MemoryContextAllocHuge

// 引数1:アロケーション対象のコンテキスト
// 引数2:アロケーションサイズ(byte)
// 戻り値:メモリチャンクのポインタ
extern void *MemoryContextAllocHuge(MemoryContext context, Size size);

repalloc_huge

// 引数1:メモリチャンクのポインタ
// 引数2:再割り当てするサイズ(byte)
// 戻り値:新しいメモリチャンクのポインタ
extern void *repalloc_huge(void *pointer, Size size);

MemoryContextSwitchTo

// 引数1:スイッチするメモリコンテキスト
// 戻り値:古い(スイッチする前の)メモリコンテキスト
MemoryContext MemoryContextSwitchTo(MemoryContext context)

 サンプル 

void memory_sample()
{
    MemoryContext context = AllocSetContextCreate(CurrentMemoryContext,
                                                   "mycontext",
                                                   0,
                                                   8 * 1024,
                                                   8 * 1024);
    MemoryContext oldcontext = MemoryContextSwitchTo(context);

    StringInfo strinfo = makeStringInfo();
    appendStringInfo(strinfo, "%s", "hoge");
    elog(NOTICE, "%s", strinfo->data);

    MemoryContextSwitchTo(oldcontext);
    MemoryContextDelete(context);
}

MemoryContextRegisterResetCallback

// 引数1:対象のメモリコンテキスト
// 引数2:reset/delete時に呼ばれるコールバック関数
extern void MemoryContextRegisterResetCallback(MemoryContext context, MemoryContextCallback *cb);

 参考  struct MemoryContextCallback - on doxygen.postgresql.org

 サンプル 

// callback function
void report_context_delete(void *arg)
{
    MemoryContext context = (MemoryContext)arg;
    elog(NOTICE, "%s will be deleted", context->name);
}

void memory_sample()
{
    MemoryContext context = AllocSetContextCreate(CurrentMemoryContext,
                                                   "mycontext",
                                                   0,
                                                   8 * 1024,
                                                   8 * 1024);
    // コールバック関数の宣言と初期化
    MemoryContextCallback callback = {
        report_context_delete, // Function Pointer
        context,               // Argument
    };

    // コールバック関数の登録
    MemoryContextRegisterResetCallback(context, &callback);

    MemoryContext oldcontext = MemoryContextSwitchTo(context);

    char *optname = palloc(16);
    strcpy(optname, "hello world");

    MemoryContextSwitchTo(oldcontext);

    // report_context_delete(context) is called
    MemoryContextDelete(context);
}

MemoryContextStrdup

// 引数1:対象のメモリコンキスト
// 引数2:複製するデータ
// 戻り値:複製されたデータのポインタ
extern char *MemoryContextStrdup(MemoryContext context, const char *string);

 参考  MemoryContextStrdup() - on doxygen.postgresql.org

pstrdup

// 引数1:複製するデータ
// 戻り値:複製されたデータのポインタ
extern char *pstrdup(const char *string);

pnstrdup

// 引数1:複製するデータ
// 引数2:複製するデータの長さ
// 戻り値:複製されたデータのポインタ
extern char *pnstrdup(const char *in, Size len);

 サンプル 

void sample() {
    const char *string = "hello world";
    size_t len = strlen(string);

    // pstrdup
    char *str = pstrdup(string);
    str[len] = '\0';
    elog(NOTICE, "str = %s", str);

    // pnstrdup
    char *str2 = pnstrdup(string, strlen(string));
    elog(NOTICE, "str2 = %s", str2);
}

psprintf

// 引数:format書式定文字列,文字列
// 戻り値:フォーマットされた文字列のポインタ
extern char *psprintf(const char *fmt,...) pg_attribute_printf(1, 2);

 参考  psprintf() - on doxygen.postgresql.org

 サンプル 

char *formatted_str = psprintf("Hello %s", "Mike");
elog(NOTICE, "%s", formatted_str); // Hello Mike

pvsnprintf

// 引数1:データを格納する領域のポインタ
// 引数2:書き込みされる最大サイズ
// 引数3:フォーマット書式指定文字列
// 引数4:書き込みするデータ
// 戻り値:書き込み長さ(nprinted)が,
//   ・len(NULL終端含む)より小さい場合は,nprinted
//   ・lenより大きい場合且つMaxAllocSize -2以下の場合は,nprinted+2
//   ・lenがMaxAllocSize / 2以上の場合は,MaxAllocSize
//   ・それ以外は,nprinted * 2
extern size_t pvsnprintf(char *buf, size_t len, const char *fmt, va_list args) pg_attribute_printf(3, 0);

 参考  pvsnprintf() - on doxygen.postgresql.org

サンプルプログラム

// オプション用の構造体
typedef struct MyExtensionOptions {
    const char *optname;
    Oid optcontext;
} MyExtensionOptions;

// delete時に呼ばれるコールバック関数
void report_context_delete(void *arg)
{
    MemoryContext context = (MemoryContext)arg;
    elog(NOTICE, "%s will be deleted", context->name);
}

// サンプル
void memory_sample2()
{
    MemoryContext oldcontext = NULL;
    // 独自のコンテキスト作成
    MemoryContext context = AllocSetContextCreate(CurrentMemoryContext,
                                                  "mycontext",
                                                  0,
                                                  8 * 1024,
                                                  8 * 1024);

    // delete時のコールバック関数を登録
    MemoryContextCallback callback = {
        report_context_delete,
        context
    };
    MemoryContextRegisterResetCallback(context, &callback);

    // カレントコンテキストを作成したメモリコンテキストに切り替え
    oldcontext = MemoryContextSwitchTo(context);

    // カレントコンテキストで色々と操作
    StringInfo strinfo = makeStringInfo();
    appendStringInfo(strinfo, "%s", "hoge");

    MyExtensionOptions *opt  = (MyExtensionOptions*)palloc(sizeof(MyExtensionOptions));
    opt->optcontext = ForeignTableRelationId;
    opt->optname = psprintf("format_%s", "csv");

    // カレントコンテキストを切り替え前に戻す
    MemoryContextSwitchTo(oldcontext);

    // 作成したメモリコンテキストを破棄する
    MemoryContextDelete(context);
}

参考・関連

 関連 

コメント



トップ   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
目次
ダブルクリックで閉じるTOP | 閉じる
GO TO TOP