Skip to content

Commit a6cb870

Browse files
author
Nikita Glukhov
committed
Optimize expanded object flattening: add context
1 parent 44c3c08 commit a6cb870

File tree

7 files changed

+51
-35
lines changed

7 files changed

+51
-35
lines changed

src/backend/access/common/heaptuple.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ heap_compute_data_size(TupleDesc tupleDesc,
120120
* tuple doesn't depend on it
121121
*/
122122
data_length = att_align_nominal(data_length, atti->attalign);
123-
data_length += EOH_get_flat_size(DatumGetEOHP(val));
123+
data_length += EOH_get_flat_size(DatumGetEOHP(val), NULL);
124124
}
125125
else
126126
{
@@ -224,11 +224,12 @@ heap_fill_tuple(TupleDesc tupleDesc,
224224
* constructed tuple doesn't depend on it
225225
*/
226226
ExpandedObjectHeader *eoh = DatumGetEOHP(values[i]);
227+
void *context;
227228

228229
data = (char *) att_align_nominal(data,
229230
att[i]->attalign);
230-
data_length = EOH_get_flat_size(eoh);
231-
EOH_flatten_into(eoh, data, data_length);
231+
data_length = EOH_get_flat_size(eoh, &context);
232+
EOH_flatten_into(eoh, data, data_length, &context);
232233
if (VARATT_IS_EXTERNAL(data))
233234
*infomask |= HEAP_HASEXTERNAL;
234235
}

src/backend/access/heap/tuptoaster.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,12 +140,13 @@ heap_tuple_fetch_attr(struct varlena * attr)
140140
* This is an expanded-object pointer --- get flat format
141141
*/
142142
ExpandedObjectHeader *eoh;
143+
void *context;
143144
Size resultsize;
144145

145146
eoh = DatumGetEOHP(PointerGetDatum(attr));
146-
resultsize = EOH_get_flat_size(eoh);
147+
resultsize = EOH_get_flat_size(eoh, &context);
147148
result = (struct varlena *) palloc(resultsize);
148-
EOH_flatten_into(eoh, (void *) result, resultsize);
149+
EOH_flatten_into(eoh, (void *) result, resultsize, &context);
149150
}
150151
else
151152
{
@@ -381,7 +382,7 @@ toast_raw_datum_size(Datum value)
381382
}
382383
else if (VARATT_IS_EXTERNAL_EXPANDED(attr))
383384
{
384-
result = EOH_get_flat_size(DatumGetEOHP(value));
385+
result = EOH_get_flat_size(DatumGetEOHP(value), NULL);
385386
}
386387
else if (VARATT_IS_COMPRESSED(attr))
387388
{
@@ -441,7 +442,7 @@ toast_datum_size(Datum value)
441442
}
442443
else if (VARATT_IS_EXTERNAL_EXPANDED(attr))
443444
{
444-
result = EOH_get_flat_size(DatumGetEOHP(value));
445+
result = EOH_get_flat_size(DatumGetEOHP(value), NULL);
445446
}
446447
else if (VARATT_IS_EXTERNAL_EXTENDED(attr))
447448
{

src/backend/utils/adt/array_expanded.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@
2121

2222

2323
/* "Methods" required for an expanded object */
24-
static Size EA_get_flat_size(ExpandedObjectHeader *eohptr);
24+
static Size EA_get_flat_size(ExpandedObjectHeader *eohptr, void **context);
2525
static void EA_flatten_into(ExpandedObjectHeader *eohptr,
26-
void *result, Size allocated_size);
26+
void *result, Size allocated_size, void **context);
2727

2828
static const ExpandedObjectMethods EA_methods =
2929
{
@@ -230,7 +230,7 @@ copy_byval_expanded_array(ExpandedArrayHeader *eah,
230230
* get_flat_size method for expanded arrays
231231
*/
232232
static Size
233-
EA_get_flat_size(ExpandedObjectHeader *eohptr)
233+
EA_get_flat_size(ExpandedObjectHeader *eohptr, void **context)
234234
{
235235
ExpandedArrayHeader *eah = (ExpandedArrayHeader *) eohptr;
236236
int nelems;
@@ -291,7 +291,7 @@ EA_get_flat_size(ExpandedObjectHeader *eohptr)
291291
*/
292292
static void
293293
EA_flatten_into(ExpandedObjectHeader *eohptr,
294-
void *result, Size allocated_size)
294+
void *result, Size allocated_size, void **context)
295295
{
296296
ExpandedArrayHeader *eah = (ExpandedArrayHeader *) eohptr;
297297
ArrayType *aresult = (ArrayType *) result;

src/backend/utils/adt/datum.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -142,10 +142,11 @@ datumCopy(Datum value, bool typByVal, int typLen)
142142
ExpandedObjectHeader *eoh = DatumGetEOHP(value);
143143
Size resultsize;
144144
char *resultptr;
145+
void *context;
145146

146-
resultsize = EOH_get_flat_size(eoh);
147+
resultsize = EOH_get_flat_size(eoh, &context);
147148
resultptr = (char *) palloc(resultsize);
148-
EOH_flatten_into(eoh, (void *) resultptr, resultsize);
149+
EOH_flatten_into(eoh, (void *) resultptr, resultsize, &context);
149150
res = PointerGetDatum(resultptr);
150151
}
151152
else
@@ -272,7 +273,7 @@ datumEstimateSpace(Datum value, bool isnull, bool typByVal, int typLen)
272273
{
273274
ExpandedObjectHeader *eoh = DatumGetEOHP(value);
274275

275-
sz += EOH_get_flat_size(eoh);
276+
sz += EOH_get_flat_size(eoh, NULL);
276277
}
277278
else
278279
sz += datumGetSize(value, typByVal, typLen);
@@ -303,6 +304,7 @@ datumSerialize(Datum value, bool isnull, bool typByVal, int typLen,
303304
char **start_address)
304305
{
305306
ExpandedObjectHeader *eoh = NULL;
307+
void *context;
306308
int header;
307309

308310
/* Write header word. */
@@ -313,7 +315,7 @@ datumSerialize(Datum value, bool isnull, bool typByVal, int typLen,
313315
else if (VARATT_IS_EXTERNAL_EXPANDED(value))
314316
{
315317
eoh = DatumGetEOHP(value);
316-
header = EOH_get_flat_size(eoh);
318+
header = EOH_get_flat_size(eoh, &context);
317319
}
318320
else
319321
header = datumGetSize(value, typByVal, typLen);
@@ -330,7 +332,7 @@ datumSerialize(Datum value, bool isnull, bool typByVal, int typLen,
330332
}
331333
else if (eoh)
332334
{
333-
EOH_flatten_into(eoh, (void *) *start_address, header);
335+
EOH_flatten_into(eoh, (void *) *start_address, header, &context);
334336
*start_address += header;
335337
}
336338
else

src/backend/utils/adt/expandeddatum.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,16 +73,17 @@ EOH_init_header(ExpandedObjectHeader *eohptr,
7373
*/
7474

7575
Size
76-
EOH_get_flat_size(ExpandedObjectHeader *eohptr)
76+
EOH_get_flat_size(ExpandedObjectHeader *eohptr, void **context)
7777
{
78-
return (*eohptr->eoh_methods->get_flat_size) (eohptr);
78+
return (*eohptr->eoh_methods->get_flat_size) (eohptr, context);
7979
}
8080

8181
void
8282
EOH_flatten_into(ExpandedObjectHeader *eohptr,
83-
void *result, Size allocated_size)
83+
void *result, Size allocated_size, void **context)
8484
{
85-
(*eohptr->eoh_methods->flatten_into) (eohptr, result, allocated_size);
85+
(*eohptr->eoh_methods->flatten_into) (eohptr, result, allocated_size,
86+
context);
8687
}
8788

8889
/*

src/backend/utils/adt/json_generic.c

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -699,7 +699,7 @@ JsonInit(Json *json)
699699
}
700700

701701
static Size
702-
jsonGetFlatSize2(Json *json)
702+
jsonGetFlatSize2(Json *json, void **context)
703703
{
704704
Size size;
705705

@@ -714,7 +714,10 @@ jsonGetFlatSize2(Json *json)
714714
{
715715
char *str = JsonToCString(&json->root);
716716
size = VARHDRSZ + strlen(str);
717-
pfree(str);
717+
if (context)
718+
*context = str;
719+
else
720+
pfree(str);
718721
}
719722
}
720723
#endif
@@ -730,7 +733,10 @@ jsonGetFlatSize2(Json *json)
730733
JsonValue val;
731734
void *js = JsonValueToJsonb(JsonToJsonValue(json, &val));
732735
size = VARSIZE(js);
733-
pfree(js);
736+
if (context)
737+
*context = js;
738+
else
739+
pfree(js);
734740
}
735741
}
736742
#endif
@@ -739,7 +745,7 @@ jsonGetFlatSize2(Json *json)
739745
}
740746

741747
static void *
742-
jsonFlatten(Json *json)
748+
jsonFlatten(Json *json, void **context)
743749
{
744750
#ifdef JSON_FLATTEN_INTO_TARGET
745751
if (json->is_json)
@@ -750,7 +756,7 @@ jsonFlatten(Json *json)
750756
return cstring_to_text_with_len(json->root.data, json->root.len);
751757
else
752758
{
753-
char *str = JsonToCString(JsonRoot(json));
759+
char *str = context ? (char *) *context : JsonToCString(JsonRoot(json));
754760
text *text = cstring_to_text(str);
755761
pfree(str);
756762
return text;
@@ -769,6 +775,8 @@ jsonFlatten(Json *json)
769775
memcpy(VARDATA(res), json->root.data, json->root.len);
770776
return res;
771777
}
778+
else if (context)
779+
return *context;
772780
else
773781
{
774782
JsonValue val;
@@ -779,7 +787,7 @@ jsonFlatten(Json *json)
779787
}
780788

781789
static Size
782-
jsonGetFlatSize(ExpandedObjectHeader *eoh)
790+
jsonGetFlatSize(ExpandedObjectHeader *eoh, void **context)
783791
{
784792
Json *json = (Json *) eoh;
785793

@@ -794,19 +802,20 @@ jsonGetFlatSize(ExpandedObjectHeader *eoh)
794802
{
795803
tmp.data = NULL;
796804
tmp.ops = flatContainerOps;
797-
tmp.len = jsonGetFlatSize2(json) - VARHDRSZ;
805+
tmp.len = jsonGetFlatSize2(json, context) - VARHDRSZ;
798806
flat = &tmp;
799807
}
800808

801809
return jsonGetExtendedSize(flat);
802810
}
803811
#else
804-
return jsonGetFlatSize2(json);
812+
return jsonGetFlatSize2(json, context);
805813
#endif
806814
}
807815

808816
static void
809-
jsonFlattenInto(ExpandedObjectHeader *eoh, void *result, Size allocated_size)
817+
jsonFlattenInto(ExpandedObjectHeader *eoh, void *result, Size allocated_size,
818+
void **context)
810819
{
811820
Json *json = (Json *) eoh;
812821

@@ -820,7 +829,7 @@ jsonFlattenInto(ExpandedObjectHeader *eoh, void *result, Size allocated_size)
820829

821830
if (flat->ops == &jsonvContainerOps)
822831
{
823-
tmpData = jsonFlatten(json);
832+
tmpData = jsonFlatten(json, context);
824833

825834
tmp.ops = flatContainerOps;
826835
tmp.data = VARDATA(tmpData);
@@ -836,7 +845,7 @@ jsonFlattenInto(ExpandedObjectHeader *eoh, void *result, Size allocated_size)
836845
}
837846
#else
838847
{
839-
void *data = jsonFlatten(json);
848+
void *data = jsonFlatten(json, context);
840849
memcpy(result, data, allocated_size);
841850
pfree(data);
842851
}

src/include/utils/expandeddatum.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,11 @@
6464
* get_flat_size twice, so it's worthwhile to make sure that that doesn't
6565
* incur too much overhead.
6666
*/
67-
typedef Size (*EOM_get_flat_size_method) (ExpandedObjectHeader *eohptr);
67+
typedef Size (*EOM_get_flat_size_method) (ExpandedObjectHeader *eohptr,
68+
void **context);
6869
typedef void (*EOM_flatten_into_method) (ExpandedObjectHeader *eohptr,
69-
void *result, Size allocated_size);
70+
void *result, Size allocated_size,
71+
void **context);
7072

7173
/* Struct of function pointers for an expanded object's methods */
7274
typedef struct ExpandedObjectMethods
@@ -149,9 +151,9 @@ extern ExpandedObjectHeader *DatumGetEOHP(Datum d);
149151
extern void EOH_init_header(ExpandedObjectHeader *eohptr,
150152
const ExpandedObjectMethods *methods,
151153
MemoryContext obj_context);
152-
extern Size EOH_get_flat_size(ExpandedObjectHeader *eohptr);
154+
extern Size EOH_get_flat_size(ExpandedObjectHeader *eohptr, void **context);
153155
extern void EOH_flatten_into(ExpandedObjectHeader *eohptr,
154-
void *result, Size allocated_size);
156+
void *result, Size allocated_size, void **context);
155157
extern Datum MakeExpandedObjectReadOnlyInternal(Datum d);
156158
extern Datum TransferExpandedObject(Datum d, MemoryContext new_parent);
157159
extern void DeleteExpandedObject(Datum d);

0 commit comments

Comments
 (0)