Skip to content

Commit fad8d2f

Browse files
committed
pathman: use of dynamic shared memory
1 parent 0137664 commit fad8d2f

File tree

5 files changed

+311
-70
lines changed

5 files changed

+311
-70
lines changed

contrib/pathman/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# contrib/pathman/Makefile
22

33
MODULE_big = pathman
4-
OBJS = init.o pathman.o $(WIN32RES)
4+
OBJS = init.o pathman.o dsm_array.o $(WIN32RES)
55

66
EXTENSION = pathman
77
EXTVERSION = 0.1

contrib/pathman/dsm_array.c

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
#include "pathman.h"
2+
#include "storage/shmem.h"
3+
#include "storage/dsm.h"
4+
#include "storage/lwlock.h"
5+
6+
7+
static Table *table;
8+
static dsm_segment *segment = NULL;
9+
10+
11+
void
12+
alloc_dsm_table()
13+
{
14+
bool foundPtr;
15+
table = (Table *) ShmemInitStruct("dsm table", sizeof(Table), &foundPtr);
16+
table->segment = 0;
17+
}
18+
19+
20+
void create_dsm_segment(size_t block_size)
21+
{
22+
bool foundPtr;
23+
dsm_handle handle;
24+
25+
/* lock here */
26+
LWLockAcquire(dsm_init_lock, LW_EXCLUSIVE);
27+
28+
/* if segment hasn't been created yet then create it */
29+
if (table->segment == 0)
30+
{
31+
/* create segment */
32+
segment = dsm_create(block_size * BLOCKS_COUNT, 0);
33+
handle = dsm_segment_handle(segment);
34+
init_dsm_table(table, handle, block_size);
35+
}
36+
/* else attach to an existing segment */
37+
else
38+
{
39+
segment = dsm_attach(table->segment);
40+
}
41+
42+
/*
43+
* Keep mapping till the end of the session. Otherwise it would be
44+
* destroyed by the end of transaction
45+
*/
46+
dsm_pin_mapping(segment);
47+
48+
/* unlock here */
49+
LWLockRelease(dsm_init_lock);
50+
}
51+
52+
void
53+
init_dsm_table(Table *tbl, dsm_handle h, size_t block_size)
54+
{
55+
int i;
56+
Block *block;
57+
// Segment *segment = dsm_attach(h);
58+
59+
// seg = dsm_create(block_size * BLOCKS_COUNT, DSM_CREATE_NULL_IF_MAXSEGMENTS);
60+
table->segment = h;
61+
table->block_size = block_size;
62+
table->first_free = 0;
63+
64+
/* create blocks */
65+
for (i=0; i<BLOCKS_COUNT; i++)
66+
{
67+
block = &table->blocks[i];
68+
block->segment = h;
69+
block->offset = i * block_size;
70+
block->is_free = true;
71+
}
72+
73+
return;
74+
}
75+
76+
/*
77+
* Allocate array inside dsm_segment
78+
*/
79+
void
80+
alloc_dsm_array(DsmArray *arr, size_t entry_size, size_t length)
81+
{
82+
int i = 0;
83+
Block *block = NULL;
84+
int free_count = 0;
85+
int size_requested = entry_size * length;
86+
int min_pos;
87+
int max_pos;
88+
89+
for (i = table->first_free; i<BLOCKS_COUNT; i++)
90+
{
91+
if (table->blocks[i].is_free)
92+
{
93+
if (!block)
94+
{
95+
block = &table->blocks[i];
96+
min_pos = i;
97+
}
98+
free_count++;
99+
}
100+
else
101+
{
102+
free_count = 0;
103+
block = NULL;
104+
}
105+
106+
if (free_count * table->block_size >= size_requested)
107+
{
108+
// return block->offset;
109+
max_pos = i;
110+
break;
111+
}
112+
}
113+
114+
/* look up for first free block */
115+
for (i = i+1; i<BLOCKS_COUNT; i++)
116+
if (table->blocks[i].is_free == true)
117+
{
118+
table->first_free = i;
119+
break;
120+
}
121+
122+
/* if we found enough of space */
123+
if (free_count * table->block_size >= size_requested)
124+
{
125+
for(i=min_pos; i<=max_pos; i++)
126+
table->blocks[i].is_free = false;
127+
arr->offset = block->offset;
128+
arr->length = length;
129+
}
130+
}
131+
132+
void
133+
free_dsm_array(DsmArray *arr)
134+
{
135+
int start = arr->offset / table->block_size;
136+
int i = 0;
137+
138+
/* set blocks free */
139+
for(;; i++)
140+
{
141+
table->blocks[start + i].is_free = false;
142+
if (i * table->block_size >= arr->length)
143+
break;
144+
}
145+
146+
arr->offset = 0;
147+
arr->length = 0;
148+
}
149+
150+
void *
151+
dsm_array_get_pointer(const DsmArray* arr)
152+
{
153+
return (uint8_t *) dsm_segment_address(segment) + arr->offset;
154+
}

contrib/pathman/init.c

Lines changed: 69 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,8 @@ void
1414
init(void)
1515
{
1616
initialization_needed = false;
17+
create_dsm_segment(32);
1718
load_part_relations_hashtable();
18-
// load_hash_restrictions_hashtable();
19-
// load_range_restrictions_hashtable();
2019
}
2120

2221
void
@@ -30,57 +29,65 @@ load_part_relations_hashtable()
3029
List *part_oids = NIL;
3130
ListCell *lc;
3231

33-
SPI_connect();
34-
ret = SPI_exec("SELECT pg_class.relfilenode, pg_attribute.attnum, pg_pathman_rels.parttype, pg_attribute.atttypid "
35-
"FROM pg_pathman_rels "
36-
"JOIN pg_class ON pg_class.relname = pg_pathman_rels.relname "
37-
"JOIN pg_attribute ON pg_attribute.attname = pg_pathman_rels.attname "
38-
"AND attrelid = pg_class.relfilenode", 0);
39-
proc = SPI_processed;
32+
LWLockAcquire(load_config_lock, LW_EXCLUSIVE);
4033

41-
if (ret > 0 && SPI_tuptable != NULL)
34+
/* if hashtable is empty */
35+
if (hash_get_num_entries(relations) == 0)
4236
{
43-
TupleDesc tupdesc = SPI_tuptable->tupdesc;
44-
SPITupleTable *tuptable = SPI_tuptable;
45-
46-
for (i=0; i<proc; i++)
37+
SPI_connect();
38+
ret = SPI_exec("SELECT pg_class.relfilenode, pg_attribute.attnum, pg_pathman_rels.parttype, pg_attribute.atttypid "
39+
"FROM pg_pathman_rels "
40+
"JOIN pg_class ON pg_class.relname = pg_pathman_rels.relname "
41+
"JOIN pg_attribute ON pg_attribute.attname = pg_pathman_rels.attname "
42+
"AND attrelid = pg_class.relfilenode", 0);
43+
proc = SPI_processed;
44+
45+
if (ret > 0 && SPI_tuptable != NULL)
4746
{
48-
HeapTuple tuple = tuptable->vals[i];
47+
TupleDesc tupdesc = SPI_tuptable->tupdesc;
48+
SPITupleTable *tuptable = SPI_tuptable;
4949

50-
int oid = DatumGetObjectId(SPI_getbinval(tuple, tupdesc, 1, &isnull));
51-
prinfo = (PartRelationInfo*)
52-
hash_search(relations, (const void *)&oid, HASH_ENTER, NULL);
53-
prinfo->oid = oid;
54-
prinfo->attnum = DatumGetInt32(SPI_getbinval(tuple, tupdesc, 2, &isnull));
55-
prinfo->parttype = DatumGetInt32(SPI_getbinval(tuple, tupdesc, 3, &isnull));
56-
prinfo->atttype = DatumGetObjectId(SPI_getbinval(tuple, tupdesc, 4, &isnull));
50+
for (i=0; i<proc; i++)
51+
{
52+
HeapTuple tuple = tuptable->vals[i];
53+
54+
int oid = DatumGetObjectId(SPI_getbinval(tuple, tupdesc, 1, &isnull));
55+
prinfo = (PartRelationInfo*)
56+
hash_search(relations, (const void *)&oid, HASH_ENTER, NULL);
57+
prinfo->oid = oid;
58+
prinfo->attnum = DatumGetInt32(SPI_getbinval(tuple, tupdesc, 2, &isnull));
59+
prinfo->parttype = DatumGetInt32(SPI_getbinval(tuple, tupdesc, 3, &isnull));
60+
prinfo->atttype = DatumGetObjectId(SPI_getbinval(tuple, tupdesc, 4, &isnull));
5761

58-
part_oids = lappend_int(part_oids, oid);
62+
part_oids = lappend_int(part_oids, oid);
5963

60-
/* children will be filled in later */
61-
// prinfo->children = NIL;
64+
/* children will be filled in later */
65+
// prinfo->children = NIL;
66+
}
6267
}
63-
}
6468

65-
/* load children information */
66-
foreach(lc, part_oids)
67-
{
68-
Oid oid = (int) lfirst_int(lc);
69+
/* load children information */
70+
foreach(lc, part_oids)
71+
{
72+
Oid oid = (int) lfirst_int(lc);
6973

70-
prinfo = (PartRelationInfo*)
71-
hash_search(relations, (const void *)&oid, HASH_FIND, NULL);
74+
prinfo = (PartRelationInfo*)
75+
hash_search(relations, (const void *)&oid, HASH_FIND, NULL);
7276

73-
switch(prinfo->parttype)
74-
{
75-
case PT_RANGE:
76-
load_range_restrictions(oid);
77-
break;
78-
case PT_HASH:
79-
load_hash_restrictions(oid);
80-
break;
77+
switch(prinfo->parttype)
78+
{
79+
case PT_RANGE:
80+
load_range_restrictions(oid);
81+
break;
82+
case PT_HASH:
83+
load_hash_restrictions(oid);
84+
break;
85+
}
8186
}
87+
SPI_finish();
8288
}
83-
SPI_finish();
89+
90+
LWLockRelease(load_config_lock);
8491
}
8592

8693
void
@@ -97,8 +104,9 @@ create_part_relations_hashtable()
97104
hash_destroy(relations);
98105

99106
relations = ShmemInitHash("Partitioning relation info",
100-
16, 16,
101-
&ctl, HASH_ELEM | HASH_BLOBS);
107+
32, 32,
108+
&ctl, HASH_ELEM);
109+
// &ctl, HASH_ELEM | HASH_BLOBS);
102110
}
103111

104112
void
@@ -137,6 +145,11 @@ load_hash_restrictions(Oid parent_oid)
137145
{
138146
TupleDesc tupdesc = SPI_tuptable->tupdesc;
139147
SPITupleTable *tuptable = SPI_tuptable;
148+
Oid *children;
149+
150+
/* allocate an array of children Oids */
151+
alloc_dsm_array(&prel->children, sizeof(Oid), proc);
152+
children = (Oid *) dsm_array_get_pointer(&prel->children);
140153

141154
for (i=0; i<proc; i++)
142155
{
@@ -151,7 +164,8 @@ load_hash_restrictions(Oid parent_oid)
151164
hashrel->child_oid = child_oid;
152165

153166
/* appending children to PartRelationInfo */
154-
prel->children[prel->children_count++] = child_oid;
167+
// prel->children[prel->children_count++] = child_oid;
168+
children[prel->children_count++] = child_oid;
155169
}
156170
}
157171

@@ -225,11 +239,19 @@ load_range_restrictions(Oid parent_oid)
225239
{
226240
TupleDesc tupdesc = SPI_tuptable->tupdesc;
227241
SPITupleTable *tuptable = SPI_tuptable;
242+
Oid *children;
243+
RangeEntry *ranges;
228244

229245
rangerel = (RangeRelation *)
230246
hash_search(range_restrictions, (void *) &parent_oid, HASH_ENTER, &found);
231247
rangerel->nranges = 0;
232248

249+
alloc_dsm_array(&prel->children, sizeof(Oid), proc);
250+
children = (Oid *) dsm_array_get_pointer(&prel->children);
251+
252+
alloc_dsm_array(&rangerel->ranges, sizeof(RangeEntry), proc);
253+
ranges = (RangeEntry *) dsm_array_get_pointer(&rangerel->ranges);
254+
233255
for (i=0; i<proc; i++)
234256
{
235257
Datum min;
@@ -279,22 +301,9 @@ load_range_restrictions(Oid parent_oid)
279301
break;
280302
}
281303

282-
// re.min = SPI_getbinval(tuple, tupdesc, 3, &arg1_isnull);
283-
// re.max = SPI_getbinval(tuple, tupdesc, 4, &arg2_isnull);
284-
// // prel->atttype = AT_INT;
285-
286-
// if (arg1_isnull || arg2_isnull)
287-
// {
288-
// re.min = SPI_getbinval(tuple, tupdesc, 5, &arg1_isnull);
289-
// re.max = SPI_getbinval(tuple, tupdesc, 6, &arg2_isnull);
290-
// // prel->atttype = AT_DATE;
291-
292-
// if (arg1_isnull || arg2_isnull)
293-
// ereport(ERROR, (errmsg("Range relation should be of type either INTEGER or DATE")));
294-
// }
295-
rangerel->ranges[rangerel->nranges++] = re;
296-
297-
prel->children[prel->children_count++] = re.child_oid;
304+
ranges[rangerel->nranges++] = re;
305+
// prel->children[prel->children_count++] = re.child_oid;
306+
children[prel->children_count++] = re.child_oid;
298307
}
299308
}
300309

0 commit comments

Comments
 (0)