Skip to content

Commit b621900

Browse files
committed
use hash table instead of merge
1 parent 3fe1b83 commit b621900

File tree

2 files changed

+47
-86
lines changed

2 files changed

+47
-86
lines changed

pickyappend.c

Lines changed: 45 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -87,61 +87,38 @@ transform_plans_into_states(PickyAppendState *scan_state,
8787
}
8888

8989
static ChildScanCommon *
90-
select_required_plans(ChildScanCommon *children, int nchildren,
91-
Oid *parts, int nparts,
92-
int *nres)
90+
select_required_plans(HTAB *children_table, Oid *parts, int nparts, int *nres)
9391
{
94-
ChildScanCommon *children_end = children + nchildren;
95-
Oid *parts_end = parts + nparts;
9692
int allocated = 10;
9793
int used = 0;
9894
ChildScanCommon *result = palloc(10 * sizeof(ChildScanCommon));
95+
int i;
9996

100-
while (children < children_end && parts < parts_end)
97+
for (i = 0; i < nparts; i++)
10198
{
102-
if ((*children)->relid < *parts)
103-
children++;
104-
else
99+
ChildScanCommon child_copy;
100+
ChildScanCommon child = hash_search(children_table,
101+
(const void *) &parts[i],
102+
HASH_FIND, NULL);
103+
if (!child)
104+
continue;
105+
106+
if (allocated <= used)
105107
{
106-
if (!(*parts < (*children)->relid))
107-
{
108-
ChildScanCommon child = palloc(sizeof(ChildScanCommonData));
109-
110-
if (allocated <= used)
111-
{
112-
allocated *= 2;
113-
result = repalloc(result, allocated * sizeof(ChildScanCommon));
114-
}
108+
allocated *= 2;
109+
result = repalloc(result, allocated * sizeof(ChildScanCommon));
110+
}
115111

116-
child->content_type = CHILD_PLAN;
117-
child->content.plan = (*children)->content.plan;
118-
child->relid = (*children)->relid;
112+
child_copy = palloc(sizeof(ChildScanCommonData));
113+
memcpy(child_copy, child, sizeof(ChildScanCommonData));
119114

120-
result[used++] = child;
121-
children++;
122-
}
123-
parts++;
124-
}
115+
result[used++] = child_copy;
125116
}
126117

127118
*nres = used;
128119
return result;
129120
}
130121

131-
/* qsort comparison function for oids */
132-
static int
133-
oid_cmp(const void *p1, const void *p2)
134-
{
135-
Oid v1 = *((const Oid *) p1);
136-
Oid v2 = *((const Oid *) p2);
137-
138-
if (v1 < v2)
139-
return -1;
140-
if (v1 > v2)
141-
return 1;
142-
return 0;
143-
}
144-
145122
static Oid *
146123
get_partition_oids(List *ranges, int *n, PartRelationInfo *prel)
147124
{
@@ -170,27 +147,10 @@ get_partition_oids(List *ranges, int *n, PartRelationInfo *prel)
170147
}
171148
}
172149

173-
if (used > 1)
174-
qsort(result, used, sizeof(Oid), oid_cmp);
175-
176150
*n = used;
177151
return result;
178152
}
179153

180-
static int
181-
cmp_child_scan_common(const void *a, const void *b)
182-
{
183-
ChildScanCommon child_a = *(ChildScanCommon *) a;
184-
ChildScanCommon child_b = *(ChildScanCommon *) b;
185-
186-
if (child_a->relid > child_b->relid)
187-
return 1;
188-
else if (child_a->relid < child_b->relid)
189-
return -1;
190-
else
191-
return 0;
192-
}
193-
194154
static Path *
195155
create_pickyappend_path(PlannerInfo *root,
196156
RelOptInfo *joinrel,
@@ -261,16 +221,12 @@ create_pickyappend_path(PlannerInfo *root,
261221
child->relid = root->simple_rte_array[relindex]->relid;
262222
Assert(child->relid != InvalidOid);
263223

264-
result->children[i++] = child;
265-
}
266-
267-
qsort(result->children, result->nchildren,
268-
sizeof(ChildScanCommon), cmp_child_scan_common);
269-
270-
/* Fill 'custom_paths' with paths in sort order */
271-
for (i = 0; i < result->nchildren; i++)
272224
result->cpath.custom_paths = lappend(result->cpath.custom_paths,
273-
result->children[i]->content.path);
225+
child->content.path);
226+
result->children[i] = child;
227+
228+
i++;
229+
}
274230

275231
return &result->cpath.path;
276232
}
@@ -357,28 +313,34 @@ save_pickyappend_private(CustomScan *cscan, PickyAppendPath *path)
357313
static void
358314
unpack_pickyappend_private(PickyAppendState *scan_state, CustomScan *cscan)
359315
{
360-
List *custom_oids = (List *) lsecond(cscan->custom_private);
361-
int nchildren = list_length(custom_oids);
362-
ChildScanCommon *children = palloc(nchildren * sizeof(ChildScanCommon));
363-
ListCell *cur_oid;
364-
ListCell *cur_plan;
365-
int i;
316+
ListCell *oid_cell;
317+
ListCell *plan_cell;
318+
List *custom_oids = (List *) lsecond(cscan->custom_private);
319+
int nchildren = list_length(custom_oids);
320+
HTAB *children_table = scan_state->children_table;
321+
HASHCTL *children_table_config = &scan_state->children_table_config;
366322

367-
i = 0;
368-
forboth (cur_oid, custom_oids, cur_plan, cscan->custom_plans)
323+
memset(children_table_config, 0, sizeof(HASHCTL));
324+
children_table_config->keysize = sizeof(Oid);
325+
children_table_config->entrysize = sizeof(ChildScanCommonData);
326+
327+
children_table = hash_create("Plan storage", nchildren,
328+
children_table_config, HASH_ELEM | HASH_BLOBS);
329+
330+
forboth (oid_cell, custom_oids, plan_cell, cscan->custom_plans)
369331
{
370-
ChildScanCommon child = palloc(sizeof(ChildScanCommonData));
332+
Oid cur_oid = lfirst_oid(oid_cell);
371333

372-
child->content_type = CHILD_PLAN;
373-
child->content.plan = (Plan *) lfirst(cur_plan);
374-
child->relid = lfirst_oid(cur_oid);
334+
ChildScanCommon child = hash_search(children_table,
335+
(const void *) &cur_oid,
336+
HASH_ENTER, NULL);
375337

376-
children[i++] = child;
338+
child->content_type = CHILD_PLAN;
339+
child->content.plan = (Plan *) lfirst(plan_cell);
377340
}
378341

342+
scan_state->children_table = children_table;
379343
scan_state->relid = linitial_oid(linitial(cscan->custom_private));
380-
scan_state->children = children;
381-
scan_state->nchildren = nchildren;
382344
}
383345

384346
Plan *
@@ -485,6 +447,7 @@ pickyappend_end(CustomScanState *node)
485447

486448
clear_plan_states(scan_state);
487449
hash_destroy(scan_state->plan_state_table);
450+
hash_destroy(scan_state->children_table);
488451
}
489452

490453
void
@@ -515,8 +478,7 @@ pickyappend_rescan(CustomScanState *node)
515478

516479
/* Select new plans for this pass */
517480
free_child_scan_common_array(scan_state->cur_plans, scan_state->ncur_plans);
518-
scan_state->cur_plans = select_required_plans(scan_state->children,
519-
scan_state->nchildren,
481+
scan_state->cur_plans = select_required_plans(scan_state->children_table,
520482
parts, nparts,
521483
&scan_state->ncur_plans);
522484
pfree(parts);

pickyappend.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,8 @@ typedef struct
4848
List *custom_exprs;
4949
List *custom_expr_states;
5050

51-
/* All available plans */
52-
ChildScanCommon *children;
53-
int nchildren;
51+
HTAB *children_table;
52+
HASHCTL children_table_config;
5453

5554
/* Currently selected plans \ plan states */
5655
ChildScanCommon *cur_plans;

0 commit comments

Comments
 (0)