Skip to content

Commit 75ac6d7

Browse files
committed
Simplify replica sorting in yb_get_tablet_metadata
1 parent 2ccb336 commit 75ac6d7

File tree

1 file changed

+70
-73
lines changed

1 file changed

+70
-73
lines changed

src/postgres/src/backend/utils/misc/pg_yb_utils.c

Lines changed: 70 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -8448,15 +8448,11 @@ YbUseMinimalCatalogCachesPreload()
84488448
return false;
84498449
}
84508450

8451-
/* Sort replica indices lexicographically while keeping parallel arrays aligned. */
8451+
/* Comparison function for sorting strings in a List */
84528452
static int
8453-
replica_index_cmp(const void *a, const void *b, void *arg)
8453+
string_list_compare(const ListCell *a, const ListCell *b)
84548454
{
8455-
const char **replicas = (const char **) arg;
8456-
int ia = *(const int *) a;
8457-
int ib = *(const int *) b;
8458-
8459-
return strcmp(replicas[ia], replicas[ib]);
8455+
return strcmp((char *) lfirst(a), (char *) lfirst(b));
84608456
}
84618457

84628458
/*
@@ -8556,97 +8552,98 @@ yb_get_tablet_metadata(PG_FUNCTION_ARGS)
85568552
nulls[6] = true;
85578553
}
85588554

8559-
/* Convert replicas array to PostgreSQL text array and JSONB attributes */
8555+
/* Convert replicas to PostgreSQL text array and build JSONB attributes */
85608556
if (tablet->replicas_count > 0)
85618557
{
85628558
size_t nreplicas = tablet->replicas_count;
8563-
int *sort_idxs;
8564-
Datum *text_elems;
8565-
JsonbParseState *jb_state = NULL;
8566-
JsonbValue jb_result;
8567-
JsonbValue jb_key;
8568-
JsonbValue jb_val;
85698559

85708560
Assert(tablet->replicas != NULL);
85718561

85728562
/* The last replica is the leader. */
85738563
values[7] = CStringGetTextDatum(tablet->replicas[nreplicas - 1]);
85748564

85758565
/*
8576-
* Build a sort index so replicas stay in lexicographic order.
8566+
* Build JSONB attributes before sorting replicas, because the
8567+
* parallel size arrays must stay aligned with the replica order.
8568+
* JSONB does not preserve key order so sorting is unnecessary.
85778569
*/
8578-
sort_idxs = palloc(nreplicas * sizeof(int));
8579-
for (size_t idx = 0; idx < nreplicas; idx++)
8580-
sort_idxs[idx] = (int) idx;
8581-
8582-
qsort_arg(sort_idxs, nreplicas, sizeof(int),
8583-
replica_index_cmp, tablet->replicas);
8584-
8585-
text_elems = palloc(nreplicas * sizeof(Datum));
8586-
8587-
/* Build JSONB: {"replicas": {"addr": {"active_sst_sizes": N, "wal_sizes": N}, ...}} */
8588-
pushJsonbValue(&jb_state, WJB_BEGIN_OBJECT, NULL);
8589-
8590-
jb_key.type = jbvString;
8591-
jb_key.val.string.val = "replicas";
8592-
jb_key.val.string.len = 8;
8593-
pushJsonbValue(&jb_state, WJB_KEY, &jb_key);
8594-
8595-
pushJsonbValue(&jb_state, WJB_BEGIN_OBJECT, NULL);
8596-
8597-
for (size_t idx = 0; idx < nreplicas; idx++)
85988570
{
8599-
int si = sort_idxs[idx];
8600-
int64 sst_size;
8601-
int64 wal_size;
8602-
8603-
text_elems[idx] = CStringGetTextDatum(tablet->replicas[si]);
8571+
JsonbParseState *jb_state = NULL;
8572+
JsonbValue jb_result;
8573+
JsonbValue jb_key;
8574+
JsonbValue jb_val;
86048575

8605-
sst_size = tablet->replica_sst_sizes
8606-
? tablet->replica_sst_sizes[si] : 0;
8607-
wal_size = tablet->replica_wal_sizes
8608-
? tablet->replica_wal_sizes[si] : 0;
8576+
/* {"replicas": {"addr": {"active_sst_sizes": N, "wal_sizes": N}, ...}} */
8577+
pushJsonbValue(&jb_state, WJB_BEGIN_OBJECT, NULL);
86098578

8610-
/* Replica address as key */
86118579
jb_key.type = jbvString;
8612-
jb_key.val.string.val = (char *) tablet->replicas[si];
8613-
jb_key.val.string.len = strlen(tablet->replicas[si]);
8580+
jb_key.val.string.val = "replicas";
8581+
jb_key.val.string.len = 8;
86148582
pushJsonbValue(&jb_state, WJB_KEY, &jb_key);
86158583

8616-
/* Per-replica object */
86178584
pushJsonbValue(&jb_state, WJB_BEGIN_OBJECT, NULL);
86188585

8619-
jb_key.type = jbvString;
8620-
jb_key.val.string.val = "active_sst_sizes";
8621-
jb_key.val.string.len = 16;
8622-
pushJsonbValue(&jb_state, WJB_KEY, &jb_key);
8623-
jb_val.type = jbvNumeric;
8624-
jb_val.val.numeric = DatumGetNumeric(
8625-
DirectFunctionCall1(int8_numeric, Int64GetDatum(sst_size)));
8626-
pushJsonbValue(&jb_state, WJB_VALUE, &jb_val);
8586+
for (size_t idx = 0; idx < nreplicas; idx++)
8587+
{
8588+
int64 sst_size;
8589+
int64 wal_size;
8590+
8591+
sst_size = tablet->replica_sst_sizes
8592+
? tablet->replica_sst_sizes[idx] : 0;
8593+
wal_size = tablet->replica_wal_sizes
8594+
? tablet->replica_wal_sizes[idx] : 0;
8595+
8596+
/* Replica address as key */
8597+
jb_key.type = jbvString;
8598+
jb_key.val.string.val = (char *) tablet->replicas[idx];
8599+
jb_key.val.string.len = strlen(tablet->replicas[idx]);
8600+
pushJsonbValue(&jb_state, WJB_KEY, &jb_key);
8601+
8602+
/* Per-replica object */
8603+
pushJsonbValue(&jb_state, WJB_BEGIN_OBJECT, NULL);
8604+
8605+
jb_key.type = jbvString;
8606+
jb_key.val.string.val = "active_sst_sizes";
8607+
jb_key.val.string.len = 16;
8608+
pushJsonbValue(&jb_state, WJB_KEY, &jb_key);
8609+
jb_val.type = jbvNumeric;
8610+
jb_val.val.numeric = DatumGetNumeric(
8611+
DirectFunctionCall1(int8_numeric, Int64GetDatum(sst_size)));
8612+
pushJsonbValue(&jb_state, WJB_VALUE, &jb_val);
8613+
8614+
jb_key.type = jbvString;
8615+
jb_key.val.string.val = "wal_sizes";
8616+
jb_key.val.string.len = 9;
8617+
pushJsonbValue(&jb_state, WJB_KEY, &jb_key);
8618+
jb_val.type = jbvNumeric;
8619+
jb_val.val.numeric = DatumGetNumeric(
8620+
DirectFunctionCall1(int8_numeric, Int64GetDatum(wal_size)));
8621+
pushJsonbValue(&jb_state, WJB_VALUE, &jb_val);
8622+
8623+
pushJsonbValue(&jb_state, WJB_END_OBJECT, NULL);
8624+
}
86278625

8628-
jb_key.type = jbvString;
8629-
jb_key.val.string.val = "wal_sizes";
8630-
jb_key.val.string.len = 9;
8631-
pushJsonbValue(&jb_state, WJB_KEY, &jb_key);
8632-
jb_val.type = jbvNumeric;
8633-
jb_val.val.numeric = DatumGetNumeric(
8634-
DirectFunctionCall1(int8_numeric, Int64GetDatum(wal_size)));
8635-
pushJsonbValue(&jb_state, WJB_VALUE, &jb_val);
8626+
pushJsonbValue(&jb_state, WJB_END_OBJECT, NULL); /* end replicas */
8627+
jb_result = *pushJsonbValue(&jb_state, WJB_END_OBJECT, NULL); /* end outer */
86368628

8637-
pushJsonbValue(&jb_state, WJB_END_OBJECT, NULL);
8629+
values[9] = JsonbPGetDatum(JsonbValueToJsonb(&jb_result));
86388630
}
86398631

8640-
pushJsonbValue(&jb_state, WJB_END_OBJECT, NULL); /* end replicas */
8641-
jb_result = *pushJsonbValue(&jb_state, WJB_END_OBJECT, NULL); /* end outer */
8632+
/* Convert char ** to List * */
8633+
{
8634+
List *replicas_list = NIL;
86428635

8643-
values[8] = PointerGetDatum(
8644-
construct_array(text_elems, (int) nreplicas,
8645-
TEXTOID, -1, false, TYPALIGN_INT));
8646-
values[9] = JsonbPGetDatum(JsonbValueToJsonb(&jb_result));
8636+
for (size_t idx = 0; idx < nreplicas; idx++)
8637+
replicas_list = lappend(replicas_list,
8638+
(char *) tablet->replicas[idx]);
86478639

8648-
pfree(sort_idxs);
8649-
pfree(text_elems);
8640+
/*
8641+
* Sort the list lexicographically for consistency, so that
8642+
* all rows with same replicas have same entries.
8643+
*/
8644+
list_sort(replicas_list, string_list_compare);
8645+
values[8] = PointerGetDatum(strlist_to_textarray(replicas_list));
8646+
}
86508647
}
86518648
else
86528649
{

0 commit comments

Comments
 (0)