preload.diff
application/octet-stream
Filename: preload.diff
Type: application/octet-stream
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: context
| File | + | − |
|---|---|---|
| contrib/dict_preload/dict_preload.c | 181 | 0 |
| contrib/dict_preload/dict_preload.sql.in | 19 | 0 |
| contrib/dict_preload/uninstall_dict_preload.sql | 10 | 0 |
| src/backend/tsearch/spell.c | 60 | 10 |
| src/backend/utils/mmgr/aset.c | 224 | 7 |
| src/include/utils/memutils.h | 9 | 0 |
*** ./contrib/dict_preload/dict_preload.c.orig 2010-03-18 17:00:33.000000000 +0100
--- ./contrib/dict_preload/dict_preload.c 2010-04-01 14:40:58.980976853 +0200
***************
*** 0 ****
--- 1,181 ----
+ /*-------------------------------------------------------------------------
+ *
+ * dict_preload.c
+ * preloaded dictionary
+ *
+ * Copyright (c) 2007-2010, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * $PostgreSQL: pgsql/contrib/dict_preload/dict_preload.c,v 1.6 2010/01/02 16:57:32 momjian Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+ #include <sys/mman.h>
+
+ #include "postgres.h"
+
+ #include "commands/defrem.h"
+ #include "fmgr.h"
+ #include "miscadmin.h"
+ #include "nodes/makefuncs.h"
+ #include "nodes/value.h"
+ #include "tsearch/ts_public.h"
+ #include "tsearch/ts_utils.h"
+ #include "tsearch/dicts/spell.h"
+ #include "utils/guc.h"
+ #include "utils/memutils.h"
+
+ PG_MODULE_MAGIC;
+
+ char *preload_dictfile = NULL;
+ char *preload_afffile = NULL;
+ char *preload_stopwords = NULL;
+
+ typedef struct
+ {
+ StopList stoplist;
+ IspellDict obj;
+ } DictISpell;
+
+ MemoryContext preload_ctx = NULL;
+
+ DictISpell *preload_dict = NULL;
+
+ PG_FUNCTION_INFO_V1(dpreloaddict_init);
+ Datum dpreloaddict_init(PG_FUNCTION_ARGS);
+
+ PG_FUNCTION_INFO_V1(dpreloaddict_lexize);
+ Datum dpreloaddict_lexize(PG_FUNCTION_ARGS);
+
+ void _PG_init(void);
+ void _PG_fini(void);
+
+ static DictISpell *
+ load_dictionary(void)
+ {
+ List *dictopt = NIL;
+ FunctionCallInfoData fcinfo;
+ DictISpell *result;
+
+ /*
+ * read parameters for preloaded dictionary
+ */
+ if (preload_dictfile != NULL)
+ dictopt = lappend(dictopt, makeDefElem("DictFile",
+ (Node *) makeString(preload_dictfile)));
+ if (preload_afffile != NULL)
+ dictopt = lappend(dictopt, makeDefElem("AffFile",
+ (Node *) makeString(preload_afffile)));
+ if (preload_stopwords != NULL)
+ dictopt = lappend(dictopt, makeDefElem("StopWords",
+ (Node *) makeString(preload_stopwords)));
+ /*
+ * Initialise ispell dictionary
+ */
+ InitFunctionCallInfoData(fcinfo, NULL, 1, NULL, NULL);
+ fcinfo.arg[0] = PointerGetDatum(dictopt);
+ fcinfo.argnull[0] = false;
+
+ result = (DictISpell *) DatumGetPointer(dispell_init(&fcinfo));
+
+
+ MemoryContextStats(CurrentMemoryContext);
+
+ return result;
+ }
+
+ Datum
+ dpreloaddict_init(PG_FUNCTION_ARGS)
+ {
+ static bool firsttime = true;
+
+ /*
+ * dpreloaddict_init can be called more times:
+ * CREATE TEXT SEARCH DICTIONARY
+ * DROP TEXT SEARCH DICTIONARY
+ * CREATE TEXT SEARCH DICTIONARY
+ * ...
+ */
+ if (firsttime)
+ {
+ /* In this moment, dictionary have to be loaded */
+ Assert(MemoryContextIsValid(preload_ctx));
+ Assert(preload_dict != NULL);
+
+ preload_ctx = NULL;
+ firsttime = false;
+
+ return PointerGetDatum(preload_dict);
+ }
+ else
+ return PointerGetDatum(load_dictionary());
+ }
+
+ Datum
+ dpreloaddict_lexize(PG_FUNCTION_ARGS)
+ {
+ return dispell_lexize(fcinfo);
+ }
+
+ /*
+ * Module load callback
+ */
+ void
+ _PG_init()
+ {
+ MemoryContext oldctx;
+ static bool inited = false;
+ GucContext guc_ctx;
+
+ if (inited)
+ return;
+ else
+ inited = true;
+
+ guc_ctx = process_shared_preload_libraries_in_progress ?
+ PGC_POSTMASTER : PGC_SUSET;
+
+ /* Define custom GUC variables. */
+ DefineCustomStringVariable("dict_preload.dictfile",
+ "name of file of preloaded ispell dictionary",
+ NULL,
+ &preload_dictfile,
+ NULL,
+ guc_ctx, 0,
+ NULL, NULL);
+
+ /* Define custom GUC variables. */
+ DefineCustomStringVariable("dict_preload.afffile",
+ "name of file of preloaded ispell affix",
+ NULL,
+ &preload_afffile,
+ NULL,
+ guc_ctx, 0,
+ NULL, NULL);
+
+ /* Define custom GUC variables. */
+ DefineCustomStringVariable("dict_preload.stopwords",
+ "name of file of preloaded ispell stopwords",
+ NULL,
+ &preload_stopwords,
+ NULL,
+ guc_ctx, 0,
+ NULL, NULL);
+
+ /* preload dictionary */
+ Assert(preload_ctx == NULL);
+ Assert(preload_dict == NULL);
+
+ preload_ctx = MMapAllocSetContextCreate(NULL, "Ispell dictionary preload context",
+ 512 * 1024,
+ 1024 * 1024 *4,
+ 1024 * 1024 *8,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_ANON,
+ -1);
+ oldctx = MemoryContextSwitchTo(preload_ctx);
+
+ preload_dict = load_dictionary();
+
+ MemoryContextSwitchTo(oldctx);
+ }
*** ./contrib/dict_preload/dict_preload.sql.in.orig 2010-03-18 17:00:52.000000000 +0100
--- ./contrib/dict_preload/dict_preload.sql.in 2010-03-19 08:24:33.000000000 +0100
***************
*** 0 ****
--- 1,19 ----
+ /* $PostgreSQL: pgsql/contrib/dict_int/dict_int.sql.in,v 1.3 2007/11/13 04:24:27 momjian Exp $ */
+
+ -- Adjust this setting to control where the objects get created.
+ SET search_path = public;
+
+ CREATE OR REPLACE FUNCTION dpreloaddict_init(internal)
+ RETURNS internal
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT;
+
+ CREATE OR REPLACE FUNCTION dpreloaddict_lexize(internal, internal, internal, internal)
+ RETURNS internal
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT;
+
+ CREATE TEXT SEARCH TEMPLATE preloaddict(
+ LEXIZE = dpreloaddict_lexize,
+ INIT = dpreloaddict_init
+ );
*** ./contrib/dict_preload/uninstall_dict_preload.sql.orig 2010-03-18 17:00:58.000000000 +0100
--- ./contrib/dict_preload/uninstall_dict_preload.sql 2010-03-18 13:52:49.000000000 +0100
***************
*** 0 ****
--- 1,10 ----
+ /* $PostgreSQL: pgsql/contrib/dict_int/uninstall_dict_int.sql,v 1.3 2007/11/13 04:24:27 momjian Exp $ */
+
+ -- Adjust this setting to control where the objects get dropped.
+ SET search_path = public;
+
+ DROP TEXT SEARCH TEMPLATE preloaddict_template CASCADE;
+
+ DROP FUNCTION dpreloaddict_init(internal);
+
+ DROP FUNCTION dpreloaddict_lexize(internal,internal,internal,internal);
*** ./src/backend/tsearch/spell.c.orig 2010-01-02 17:57:53.000000000 +0100
--- ./src/backend/tsearch/spell.c 2010-04-01 15:09:06.512848296 +0200
***************
*** 31,36 ****
--- 31,41 ----
#define tmpalloc(sz) MemoryContextAlloc(tmpCtx, (sz))
#define tmpalloc0(sz) MemoryContextAllocZero(tmpCtx, (sz))
+ static void *simple_alloc_ptr;
+ static Size simple_alloc_free;
+
+ #define SIMPLE_ALLOC_BLOCKSIZE (1024 * 1024 * 2)
+
static void
checkTmpCtx(void)
{
***************
*** 45,50 ****
--- 50,56 ----
ALLOCSET_DEFAULT_MINSIZE,
ALLOCSET_DEFAULT_INITSIZE,
ALLOCSET_DEFAULT_MAXSIZE);
+ simple_alloc_free = 0;
}
else
tmpCtx = CurrentMemoryContext->firstchild;
***************
*** 63,68 ****
--- 69,118 ----
return dst;
}
+ static void *
+ simple_alloc(Size size)
+ {
+ void *ptr;
+
+ size = MAXALIGN(size);
+
+ if (size > simple_alloc_free)
+ {
+ simple_alloc_ptr = palloc(SIMPLE_ALLOC_BLOCKSIZE);
+ simple_alloc_free = SIMPLE_ALLOC_BLOCKSIZE;
+ }
+
+ ptr = simple_alloc_ptr;
+ simple_alloc_ptr = (char *) simple_alloc_ptr + size;
+ simple_alloc_free -= size;
+
+ return ptr;
+ }
+
+ static void *
+ simple_alloc0(Size size)
+ {
+ void *ptr;
+
+ ptr = simple_alloc(size);
+ memset(ptr, 0, size);
+
+ return ptr;
+ }
+
+ static char *
+ simple_strdup(char *str)
+ {
+ char *result;
+ int len;
+
+ len = strlen(str);
+ result = simple_alloc(len + 1);
+ memcpy(result, str, len + 1);
+
+ return result;
+ }
+
#define MAX_NORM 1024
#define MAXNORMLEN 256
***************
*** 375,383 ****
Affix->flag = flag;
Affix->type = type;
! Affix->find = (find && *find) ? pstrdup(find) : VoidString;
if ((Affix->replen = strlen(repl)) > 0)
! Affix->repl = pstrdup(repl);
else
Affix->repl = VoidString;
Conf->naffixes++;
--- 425,433 ----
Affix->flag = flag;
Affix->type = type;
! Affix->find = (find && *find) ? simple_strdup(find) : VoidString;
if ((Affix->replen = strlen(repl)) > 0)
! Affix->repl = simple_strdup(repl);
else
Affix->repl = VoidString;
Conf->naffixes++;
***************
*** 833,839 ****
}
ptr = Conf->AffixData + Conf->nAffixData;
! *ptr = palloc(strlen(Conf->AffixData[a1]) + strlen(Conf->AffixData[a2]) +
1 /* space */ + 1 /* \0 */ );
sprintf(*ptr, "%s %s", Conf->AffixData[a1], Conf->AffixData[a2]);
ptr++;
--- 883,889 ----
}
ptr = Conf->AffixData + Conf->nAffixData;
! *ptr = simple_alloc(strlen(Conf->AffixData[a1]) + strlen(Conf->AffixData[a2]) +
1 /* space */ + 1 /* \0 */ );
sprintf(*ptr, "%s %s", Conf->AffixData[a1], Conf->AffixData[a2]);
ptr++;
***************
*** 878,884 ****
if (!nchar)
return NULL;
! rs = (SPNode *) palloc0(SPNHDRSZ + nchar * sizeof(SPNodeData));
rs->length = nchar;
data = rs->data;
--- 928,934 ----
if (!nchar)
return NULL;
! rs = (SPNode *) simple_alloc0(SPNHDRSZ + nchar * sizeof(SPNodeData));
rs->length = nchar;
data = rs->data;
***************
*** 974,980 ****
{
curaffix++;
Assert(curaffix < naffix);
! Conf->AffixData[curaffix] = pstrdup(Conf->Spell[i]->p.flag);
}
Conf->Spell[i]->p.d.affix = curaffix;
--- 1024,1030 ----
{
curaffix++;
Assert(curaffix < naffix);
! Conf->AffixData[curaffix] = simple_strdup(Conf->Spell[i]->p.flag);
}
Conf->Spell[i]->p.d.affix = curaffix;
***************
*** 1014,1020 ****
aff = (AFFIX **) tmpalloc(sizeof(AFFIX *) * (high - low + 1));
naff = 0;
! rs = (AffixNode *) palloc0(ANHRDSZ + nchar * sizeof(AffixNodeData));
rs->length = nchar;
data = rs->data;
--- 1064,1070 ----
aff = (AFFIX **) tmpalloc(sizeof(AFFIX *) * (high - low + 1));
naff = 0;
! rs = (AffixNode *) simple_alloc0(ANHRDSZ + nchar * sizeof(AffixNodeData));
rs->length = nchar;
data = rs->data;
***************
*** 1030,1036 ****
if (naff)
{
data->naff = naff;
! data->aff = (AFFIX **) palloc(sizeof(AFFIX *) * naff);
memcpy(data->aff, aff, sizeof(AFFIX *) * naff);
naff = 0;
}
--- 1080,1086 ----
if (naff)
{
data->naff = naff;
! data->aff = (AFFIX **) simple_alloc(sizeof(AFFIX *) * naff);
memcpy(data->aff, aff, sizeof(AFFIX *) * naff);
naff = 0;
}
***************
*** 1050,1056 ****
if (naff)
{
data->naff = naff;
! data->aff = (AFFIX **) palloc(sizeof(AFFIX *) * naff);
memcpy(data->aff, aff, sizeof(AFFIX *) * naff);
naff = 0;
}
--- 1100,1106 ----
if (naff)
{
data->naff = naff;
! data->aff = (AFFIX **) simple_alloc(sizeof(AFFIX *) * naff);
memcpy(data->aff, aff, sizeof(AFFIX *) * naff);
naff = 0;
}
***************
*** 1067,1073 ****
cnt = 0;
int start = (issuffix) ? startsuffix : 0;
int end = (issuffix) ? Conf->naffixes : startsuffix;
! AffixNode *Affix = (AffixNode *) palloc0(ANHRDSZ + sizeof(AffixNodeData));
Affix->length = 1;
Affix->isvoid = 1;
--- 1117,1123 ----
cnt = 0;
int start = (issuffix) ? startsuffix : 0;
int end = (issuffix) ? Conf->naffixes : startsuffix;
! AffixNode *Affix = (AffixNode *) simple_alloc0(ANHRDSZ + sizeof(AffixNodeData));
Affix->length = 1;
Affix->isvoid = 1;
***************
*** 1091,1097 ****
if (cnt == 0)
return;
! Affix->data->aff = (AFFIX **) palloc(sizeof(AFFIX *) * cnt);
Affix->data->naff = (uint32) cnt;
cnt = 0;
--- 1141,1147 ----
if (cnt == 0)
return;
! Affix->data->aff = (AFFIX **) simple_alloc(sizeof(AFFIX *) * cnt);
Affix->data->naff = (uint32) cnt;
cnt = 0;
*** ./src/backend/utils/mmgr/aset.c.orig 2010-02-26 03:01:14.000000000 +0100
--- ./src/backend/utils/mmgr/aset.c 2010-04-01 14:16:33.719848482 +0200
***************
*** 62,67 ****
--- 62,71 ----
*-------------------------------------------------------------------------
*/
+ #include <sys/mman.h>
+ #include <unistd.h>
+ #include <stdlib.h>
+
#include "postgres.h"
#include "utils/memutils.h"
***************
*** 122,127 ****
--- 126,155 ----
typedef void *AllocPointer;
/*
+ * This is the virtual table for external memory methods
+ */
+ typedef struct MemoryAccessMethods
+ {
+ void *data; /* pointer on data used for external allocator */
+ void *(*alloc) (Size size, void *data);
+ void *(*realloc) (void *ptr, Size size, void *data);
+ void (*free) (void *ptr, void *data);
+ } MemoryAccessMethods;
+
+ typedef struct MMapMemoryContextData
+ {
+ int prot;
+ int flags;
+ int fd;
+ } MMapMemoryContextData;
+
+ #define ALLOC(_ctx, size) (*_ctx->methods->alloc) (size, _ctx->methods->data)
+ #define REALLOC(_ctx, ptr, size) (*_ctx->methods->realloc) (ptr, size, _ctx->methods->data)
+ #define FREE(_ctx, ptr) (*_ctx->methods->free) (ptr, _ctx->methods->data)
+
+ #define PAGE_ALIGN(size) (((size) / getpagesize() + 1) * getpagesize())
+
+ /*
* AllocSetContext is our standard implementation of MemoryContext.
*
* Note: isReset means there is nothing for AllocSetReset to do. This is
***************
*** 143,148 ****
--- 171,177 ----
Size nextBlockSize; /* next block size to allocate */
Size allocChunkLimit; /* effective chunk size limit */
AllocBlock keeper; /* if not NULL, keep this block over resets */
+ MemoryAccessMethods *methods;
} AllocSetContext;
typedef AllocSetContext *AllocSet;
***************
*** 220,225 ****
--- 249,270 ----
static void AllocSetCheck(MemoryContext context);
#endif
+ static void *memory_alloc(Size size, void *data);
+ static void *memory_realloc(void *ptr, Size size, void *data);
+ static void memory_free(void *ptr, void *data);
+
+ static void *mmap_alloc(Size size, void *data);
+ static void *mmap_realloc(void *ptr, Size size, void *data);
+ static void mmap_free(void *ptr, void *data);
+
+ static MemoryContext
+ _AllocSetContextCreate(MemoryContext parent, const char *name,
+ Size minContextSize,
+ Size initBlockSize,
+ Size maxBlockSize,
+ MemoryAccessMethods *methods);
+
+
/*
* This is the virtual function table for AllocSet contexts.
*/
***************
*** 238,243 ****
--- 283,295 ----
#endif
};
+ static MemoryAccessMethods MemoryAccess = {
+ NULL, /* there are no special data */
+ memory_alloc,
+ memory_realloc,
+ memory_free
+ };
+
/*
* Table for AllocSetFreeIndex
*/
***************
*** 266,271 ****
--- 318,324 ----
#define AllocAllocInfo(_cxt, _chunk)
#endif
+
/* ----------
* AllocSetFreeIndex -
*
***************
*** 353,358 ****
--- 406,427 ----
Size initBlockSize,
Size maxBlockSize)
{
+ return _AllocSetContextCreate(parent, name,
+ minContextSize,
+ initBlockSize,
+ maxBlockSize,
+ &MemoryAccess);
+ }
+
+
+ static MemoryContext
+ _AllocSetContextCreate(MemoryContext parent,
+ const char *name,
+ Size minContextSize,
+ Size initBlockSize,
+ Size maxBlockSize,
+ MemoryAccessMethods *methods)
+ {
AllocSet context;
/* Do the type-independent part of context creation */
***************
*** 376,381 ****
--- 445,451 ----
context->initBlockSize = initBlockSize;
context->maxBlockSize = maxBlockSize;
context->nextBlockSize = initBlockSize;
+ context->methods = methods;
/*
* Compute the allocation chunk size limit for this context. It can't be
***************
*** 399,405 ****
Size blksize = MAXALIGN(minContextSize);
AllocBlock block;
! block = (AllocBlock) malloc(blksize);
if (block == NULL)
{
MemoryContextStats(TopMemoryContext);
--- 469,475 ----
Size blksize = MAXALIGN(minContextSize);
AllocBlock block;
! block = (AllocBlock) ALLOC(context, blksize);
if (block == NULL)
{
MemoryContextStats(TopMemoryContext);
***************
*** 503,509 ****
/* Wipe freed memory for debugging purposes */
memset(block, 0x7F, block->freeptr - ((char *) block));
#endif
! free(block);
}
block = next;
}
--- 573,579 ----
/* Wipe freed memory for debugging purposes */
memset(block, 0x7F, block->freeptr - ((char *) block));
#endif
! FREE(set, block);
}
block = next;
}
***************
*** 578,584 ****
{
chunk_size = MAXALIGN(size);
blksize = chunk_size + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ;
! block = (AllocBlock) malloc(blksize);
if (block == NULL)
{
MemoryContextStats(TopMemoryContext);
--- 648,654 ----
{
chunk_size = MAXALIGN(size);
blksize = chunk_size + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ;
! block = (AllocBlock) ALLOC(set, blksize);
if (block == NULL)
{
MemoryContextStats(TopMemoryContext);
***************
*** 748,754 ****
blksize <<= 1;
/* Try to allocate it */
! block = (AllocBlock) malloc(blksize);
/*
* We could be asking for pretty big blocks here, so cope if malloc
--- 818,824 ----
blksize <<= 1;
/* Try to allocate it */
! block = (AllocBlock) ALLOC(set, blksize);
/*
* We could be asking for pretty big blocks here, so cope if malloc
***************
*** 759,765 ****
blksize >>= 1;
if (blksize < required_size)
break;
! block = (AllocBlock) malloc(blksize);
}
if (block == NULL)
--- 829,835 ----
blksize >>= 1;
if (blksize < required_size)
break;
! block = (AllocBlock) ALLOC(set, blksize);
}
if (block == NULL)
***************
*** 870,876 ****
/* Wipe freed memory for debugging purposes */
memset(block, 0x7F, block->freeptr - ((char *) block));
#endif
! free(block);
}
else
{
--- 940,946 ----
/* Wipe freed memory for debugging purposes */
memset(block, 0x7F, block->freeptr - ((char *) block));
#endif
! FREE(set, block);
}
else
{
***************
*** 967,973 ****
/* Do the realloc */
chksize = MAXALIGN(size);
blksize = chksize + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ;
! block = (AllocBlock) realloc(block, blksize);
if (block == NULL)
{
MemoryContextStats(TopMemoryContext);
--- 1037,1043 ----
/* Do the realloc */
chksize = MAXALIGN(size);
blksize = chksize + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ;
! block = (AllocBlock) REALLOC(set, block, blksize);
if (block == NULL)
{
MemoryContextStats(TopMemoryContext);
***************
*** 1199,1201 ****
--- 1269,1418 ----
}
#endif /* MEMORY_CONTEXT_CHECKING */
+
+ /*
+ * Methods for access to glibc space
+ */
+ static void *
+ memory_alloc(Size size, void *data)
+ {
+ return malloc(size);
+ }
+
+ static void *
+ memory_realloc(void *ptr, Size size, void *data)
+ {
+ return realloc(ptr, size);
+ }
+
+ static void
+ memory_free(void *ptr, void *data)
+ {
+ free(ptr);
+ }
+
+
+ /*
+ * Methods for access to mmap space
+ */
+ MemoryContext
+ MMapAllocSetContextCreate(MemoryContext parent,
+ const char *name,
+ Size minContextSize,
+ Size initBlockSize,
+ Size maxBlockSize,
+ int prot,
+ int flags,
+ int fd)
+ {
+ MMapMemoryContextData *mmap_data;
+ MemoryAccessMethods *mmap_access;
+
+ mmap_data = MemoryContextAlloc(TopMemoryContext,
+ sizeof(MMapMemoryContextData));
+ mmap_data->prot = prot;
+ mmap_data->flags = flags;
+ mmap_data->fd = fd;
+
+ mmap_access = MemoryContextAlloc(TopMemoryContext,
+ sizeof(MemoryAccessMethods));
+
+ mmap_access->data = mmap_data;
+ mmap_access->alloc = mmap_alloc;
+ mmap_access->realloc = mmap_realloc;
+ mmap_access->free = mmap_free;
+
+ return _AllocSetContextCreate(parent, name,
+ minContextSize,
+ initBlockSize,
+ maxBlockSize,
+ mmap_access);
+ }
+
+ static void *
+ mmap_alloc(Size size, void *data)
+ {
+ void *ptr;
+ MMapMemoryContextData *mmdata = (MMapMemoryContextData *) data;
+
+ Assert(mmdata != NULL);
+
+ size = PAGE_ALIGN(MAXALIGN(size) + MAXALIGN(sizeof(size)));
+
+ ptr = mmap(NULL, size, mmdata->prot, mmdata->flags,
+ -1, 0);
+
+ if (ptr == MAP_FAILED)
+ ereport(ERROR,
+ (errcode(ERRCODE_OUT_OF_MEMORY),
+ errmsg("out of memory"),
+ errdetail("Failed on request of size %lu.",
+ (unsigned long) size)));
+
+ *((Size*) ptr) = size;
+ return (char *) ptr + MAXALIGN(sizeof(Size));
+ }
+
+ static void *
+ mmap_realloc(void *ptr, Size size, void *data)
+ {
+ MMapMemoryContextData *mmdata = (MMapMemoryContextData *) data;
+ Size oldsize;
+ void *result = ptr;
+
+ ptr = (char *) ptr - MAXALIGN(sizeof(Size));
+
+ oldsize = *((Size *) ptr);
+ size = PAGE_ALIGN(MAXALIGN(size) + MAXALIGN(sizeof(Size)));
+
+ Assert(mmdata != NULL);
+
+ /*
+ * Attention - on linux you cannot call mremap together with
+ * shared
+ *
+ * ptr = mremap(ptr, oldsize,
+ * size,
+ * MREMAP_MAYMOVE);
+ */
+ if (size > oldsize)
+ {
+ void *newptr;
+ Size newsize = oldsize;
+
+ while (newsize < size)
+ newsize = PAGE_ALIGN(2 * newsize);
+
+ newptr = mmap(NULL, newsize,
+ mmdata->prot, mmdata->flags, mmdata->fd,
+ 0);
+
+ if (newptr == MAP_FAILED)
+ ereport(ERROR,
+ (errcode(ERRCODE_OUT_OF_MEMORY),
+ errmsg("out of memory"),
+ errdetail("Failed on request of size %lu.",
+ (unsigned long) newsize)));
+ memcpy(newptr, ptr, oldsize);
+ *((Size*) newptr) = newsize;
+
+ munmap(ptr, oldsize);
+ result = (char *) newptr + MAXALIGN(sizeof(Size));
+ }
+
+ return result;
+ }
+
+ static void
+ mmap_free(void *ptr, void *data)
+ {
+ Size size;
+ MMapMemoryContextData *mmdata = (MMapMemoryContextData *) data;
+
+ Assert(mmdata != NULL);
+
+ ptr = (char *) ptr - MAXALIGN(sizeof(Size));
+ size = *((Size*) ptr);
+
+ munmap(ptr, size);
+ }
*** ./src/include/utils/memutils.h.orig 2010-01-02 17:58:10.000000000 +0100
--- ./src/include/utils/memutils.h 2010-04-01 14:18:33.319326916 +0200
***************
*** 120,125 ****
--- 120,134 ----
Size initBlockSize,
Size maxBlockSize);
+ extern MemoryContext MMapAllocSetContextCreate(MemoryContext parent,
+ const char *name,
+ Size minContextSize,
+ Size initBlockSize,
+ Size maxBlockSize,
+ int prot,
+ int flags,
+ int fd);
+
/*
* Recommended default alloc parameters, suitable for "ordinary" contexts
* that might hold quite a lot of data.