Skip to content

Commit 99c50d4

Browse files
committed
MVT: Improve performance and memory usage
- Reduce memory usage (raises protobuf-c requirement to 1.1). - Improves performance when merging tiles (from parallel queries). - Uses protobuf values to reduce the number of transformations and memory usage. - Uses a temporal context when transforming data (reading rows) to have a fast way of cleaning up memory before the parallel process starts. - Processes texts and cstrings with each known reading functions instead of the `OidOutputFunctionCall` fallback. - Avoids multiple hash function calls when a value is not found in the hash table (once for the lookup and once for the insertion). Closes #576 Closes #4737
1 parent 9ef9130 commit 99c50d4

6 files changed

Lines changed: 235 additions & 278 deletions

File tree

NEWS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ PostGIS 3.1.0beta1
22
2020/xx/xx
33
Only tickets not included in 3.1.0alpha2
44

5+
* Breaking changes *
6+
- #4737, Bump minimum protobuf-c requirement to 1.1.0 (Raúl Marín)
7+
58
* New features *
69
- #4698, Add a precision parameter to ST_AsEWKT (Raúl Marín)
710

@@ -23,6 +26,8 @@ Only tickets not included in 3.1.0alpha2
2326
ST_BoundingDiagonal.
2427
- #4741, Don't use ST_PointInsideCircle if you need indexes, use ST_DWithin instead.
2528
Documentation adjusted (Darafei Praliaskouski)
29+
- #4737, Improve performance and reduce memory usage in ST_AsMVT, especially in
30+
queries involving parallelism (Raúl Marín)
2631

2732
* Bug fixes *
2833
- #4691, Fix segfault during gist index creation with empty geometries (Raúl Marín)

configure.ac

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -998,7 +998,7 @@ if test "$CHECK_PROTOBUF" != "no"; then
998998
dnl Try pkgconfig first
999999
if test -n "$PKG_CONFIG"; then
10001000
dnl Ensure libprotobuf-c is of minimum required version
1001-
PKG_CHECK_MODULES([PROTOBUFC], [libprotobuf-c >= 1.0.0], [
1001+
PKG_CHECK_MODULES([PROTOBUFC], [libprotobuf-c >= 1.1.0], [
10021002
PROTOBUF_CPPFLAGS="$PROTOBUFC_CFLAGS";
10031003
PROTOBUF_LDFLAGS="$PROTOBUFC_LIBS";
10041004
], [
@@ -1069,10 +1069,8 @@ if test "$CHECK_PROTOBUF" != "no"; then
10691069
if test "$HAVE_PROTOBUF" = "yes"; then
10701070
AC_DEFINE([HAVE_LIBPROTOBUF], [1], [Define to 1 if libprotobuf-c is present])
10711071
AC_DEFINE_UNQUOTED([LIBPROTOBUF_VERSION], [$PROTOC_VERSION], [Numeric version number for libprotobuf-c])
1072-
if test $PROTOC_VERSION -ge 1001000; then
1073-
AC_DEFINE([HAVE_GEOBUF], [1], [Define to 1 if libprotobuf is >= 1.1])
1074-
HAVE_GEOBUF=yes
1075-
fi
1072+
AC_DEFINE([HAVE_GEOBUF], [1], [Define to 1 if geobuf is present])
1073+
HAVE_GEOBUF=yes
10761074
fi
10771075

10781076
AC_SUBST([HAVE_PROTOBUF])

postgis/lwgeom_out_mvt.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,14 +129,14 @@ Datum pgis_asmvt_transfn(PG_FUNCTION_ARGS)
129129
elog(ERROR, "Missing libprotobuf-c");
130130
PG_RETURN_NULL();
131131
#else
132-
MemoryContext aggcontext;
132+
MemoryContext aggcontext, old_context;
133133
mvt_agg_context *ctx;
134134

135135
if (!AggCheckCallContext(fcinfo, &aggcontext))
136136
elog(ERROR, "%s called in non-aggregate context", __func__);
137-
MemoryContextSwitchTo(aggcontext);
138137

139138
if (PG_ARGISNULL(0)) {
139+
old_context = MemoryContextSwitchTo(aggcontext);
140140
ctx = palloc(sizeof(*ctx));
141141
ctx->name = "default";
142142
if (PG_NARGS() > 2 && !PG_ARGISNULL(2))
@@ -151,7 +151,12 @@ Datum pgis_asmvt_transfn(PG_FUNCTION_ARGS)
151151
ctx->id_name = text_to_cstring(PG_GETARG_TEXT_P(5));
152152
else
153153
ctx->id_name = NULL;
154+
155+
ctx->trans_context = AllocSetContextCreate(aggcontext, "MVT transfn", ALLOCSET_DEFAULT_SIZES);
156+
157+
MemoryContextSwitchTo(ctx->trans_context);
154158
mvt_agg_init_context(ctx);
159+
MemoryContextSwitchTo(old_context);
155160
} else {
156161
ctx = (mvt_agg_context *) PG_GETARG_POINTER(0);
157162
}
@@ -160,7 +165,10 @@ Datum pgis_asmvt_transfn(PG_FUNCTION_ARGS)
160165
elog(ERROR, "%s: parameter row cannot be other than a rowtype", __func__);
161166
ctx->row = PG_GETARG_HEAPTUPLEHEADER(1);
162167

168+
old_context = MemoryContextSwitchTo(ctx->trans_context);
163169
mvt_agg_transfn(ctx);
170+
MemoryContextSwitchTo(old_context);
171+
164172
PG_FREE_IF_COPY(ctx->row, 1);
165173
PG_RETURN_POINTER(ctx);
166174
#endif
@@ -203,6 +211,7 @@ Datum pgis_asmvt_serialfn(PG_FUNCTION_ARGS)
203211
PG_RETURN_NULL();
204212
#else
205213
mvt_agg_context *ctx;
214+
bytea *result;
206215
elog(DEBUG2, "%s called", __func__);
207216
if (!AggCheckCallContext(fcinfo, NULL))
208217
elog(ERROR, "%s called in non-aggregate context", __func__);
@@ -215,7 +224,11 @@ Datum pgis_asmvt_serialfn(PG_FUNCTION_ARGS)
215224
}
216225

217226
ctx = (mvt_agg_context *) PG_GETARG_POINTER(0);
218-
PG_RETURN_BYTEA_P(mvt_ctx_serialize(ctx));
227+
result = mvt_ctx_serialize(ctx);
228+
if (ctx->trans_context)
229+
MemoryContextDelete(ctx->trans_context);
230+
ctx->trans_context = NULL;
231+
PG_RETURN_BYTEA_P(result);
219232
#endif
220233
}
221234

0 commit comments

Comments
 (0)