Implement List support for TransactionId

Use it for RelationSyncEntry->streamed_txns, which is currently using an
integer list.

The API support is not complete, not because it is hard to write but
because it's unclear that it's worth the code space, there being so
little use of XID lists.

Discussion: https://postgr.es/m/202205130830.g5ntonhztspb@alvherre.pgsql
Reviewed-by: Amit Kapila <amit.kapila16@gmail.com>
This commit is contained in:
Alvaro Herrera 2022-07-04 14:52:12 +02:00
parent 55f4802785
commit f10a025cfe
No known key found for this signature in database
GPG Key ID: 1C20ACB9D5C564AE
5 changed files with 70 additions and 12 deletions

View File

@ -54,6 +54,7 @@
#define IsPointerList(l) ((l) == NIL || IsA((l), List))
#define IsIntegerList(l) ((l) == NIL || IsA((l), IntList))
#define IsOidList(l) ((l) == NIL || IsA((l), OidList))
#define IsXidList(l) ((l) == NIL || IsA((l), XidList))
#ifdef USE_ASSERT_CHECKING
/*
@ -71,7 +72,8 @@ check_list_invariants(const List *list)
Assert(list->type == T_List ||
list->type == T_IntList ||
list->type == T_OidList);
list->type == T_OidList ||
list->type == T_XidList);
}
#else
#define check_list_invariants(l) ((void) 0)
@ -383,6 +385,24 @@ lappend_oid(List *list, Oid datum)
return list;
}
/*
* Append a TransactionId to the specified list. See lappend()
*/
List *
lappend_xid(List *list, TransactionId datum)
{
Assert(IsXidList(list));
if (list == NIL)
list = new_list(T_XidList, 1);
else
new_tail_cell(list);
llast_xid(list) = datum;
check_list_invariants(list);
return list;
}
/*
* Make room for a new cell at position 'pos' (measured from 0).
* The data in the cell is left undefined, and must be filled in by the
@ -714,6 +734,26 @@ list_member_oid(const List *list, Oid datum)
return false;
}
/*
* Return true iff the TransactionId 'datum' is a member of the list.
*/
bool
list_member_xid(const List *list, TransactionId datum)
{
const ListCell *cell;
Assert(IsXidList(list));
check_list_invariants(list);
foreach(cell, list)
{
if (lfirst_oid(cell) == datum)
return true;
}
return false;
}
/*
* Delete the n'th cell (counting from 0) in list.
*

View File

@ -221,6 +221,8 @@ _outList(StringInfo str, const List *node)
appendStringInfoChar(str, 'i');
else if (IsA(node, OidList))
appendStringInfoChar(str, 'o');
else if (IsA(node, XidList))
appendStringInfoChar(str, 'x');
foreach(lc, node)
{
@ -239,6 +241,8 @@ _outList(StringInfo str, const List *node)
appendStringInfo(str, " %d", lfirst_int(lc));
else if (IsA(node, OidList))
appendStringInfo(str, " %u", lfirst_oid(lc));
else if (IsA(node, XidList))
appendStringInfo(str, " %u", lfirst_xid(lc));
else
elog(ERROR, "unrecognized list node type: %d",
(int) node->type);

View File

@ -1923,15 +1923,7 @@ init_rel_sync_cache(MemoryContext cachectx)
static bool
get_schema_sent_in_streamed_txn(RelationSyncEntry *entry, TransactionId xid)
{
ListCell *lc;
foreach(lc, entry->streamed_txns)
{
if (xid == (uint32) lfirst_int(lc))
return true;
}
return false;
return list_member_xid(entry->streamed_txns, xid);
}
/*
@ -1945,7 +1937,7 @@ set_schema_sent_in_streamed_txn(RelationSyncEntry *entry, TransactionId xid)
oldctx = MemoryContextSwitchTo(CacheMemoryContext);
entry->streamed_txns = lappend_int(entry->streamed_txns, xid);
entry->streamed_txns = lappend_xid(entry->streamed_txns, xid);
MemoryContextSwitchTo(oldctx);
}
@ -2248,7 +2240,7 @@ cleanup_rel_sync_cache(TransactionId xid, bool is_commit)
*/
foreach(lc, entry->streamed_txns)
{
if (xid == (uint32) lfirst_int(lc))
if (xid == lfirst_xid(lc))
{
if (is_commit)
entry->schema_sent = true;

View File

@ -317,6 +317,7 @@ typedef enum NodeTag
T_List,
T_IntList,
T_OidList,
T_XidList,
/*
* TAGS FOR EXTENSIBLE NODES (extensible.h)

View File

@ -45,6 +45,7 @@ typedef union ListCell
void *ptr_value;
int int_value;
Oid oid_value;
TransactionId xid_value;
} ListCell;
typedef struct List
@ -169,6 +170,7 @@ list_length(const List *l)
#define lfirst(lc) ((lc)->ptr_value)
#define lfirst_int(lc) ((lc)->int_value)
#define lfirst_oid(lc) ((lc)->oid_value)
#define lfirst_xid(lc) ((lc)->xid_value)
#define lfirst_node(type,lc) castNode(type, lfirst(lc))
#define linitial(l) lfirst(list_nth_cell(l, 0))
@ -194,6 +196,7 @@ list_length(const List *l)
#define llast(l) lfirst(list_last_cell(l))
#define llast_int(l) lfirst_int(list_last_cell(l))
#define llast_oid(l) lfirst_oid(list_last_cell(l))
#define llast_xid(l) lfirst_xid(list_last_cell(l))
#define llast_node(type,l) castNode(type, llast(l))
/*
@ -202,6 +205,7 @@ list_length(const List *l)
#define list_make_ptr_cell(v) ((ListCell) {.ptr_value = (v)})
#define list_make_int_cell(v) ((ListCell) {.int_value = (v)})
#define list_make_oid_cell(v) ((ListCell) {.oid_value = (v)})
#define list_make_xid_cell(v) ((ListCell) {.xid_value = (v)})
#define list_make1(x1) \
list_make1_impl(T_List, list_make_ptr_cell(x1))
@ -248,6 +252,21 @@ list_length(const List *l)
list_make_oid_cell(x3), list_make_oid_cell(x4), \
list_make_oid_cell(x5))
#define list_make1_xid(x1) \
list_make1_impl(T_XidList, list_make_xid_cell(x1))
#define list_make2_xid(x1,x2) \
list_make2_impl(T_XidList, list_make_xid_cell(x1), list_make_xid_cell(x2))
#define list_make3_xid(x1,x2,x3) \
list_make3_impl(T_XidList, list_make_xid_cell(x1), list_make_xid_cell(x2), \
list_make_xid_cell(x3))
#define list_make4_xid(x1,x2,x3,x4) \
list_make4_impl(T_XidList, list_make_xid_cell(x1), list_make_xid_cell(x2), \
list_make_xid_cell(x3), list_make_xid_cell(x4))
#define list_make5_xid(x1,x2,x3,x4,x5) \
list_make5_impl(T_XidList, list_make_xid_cell(x1), list_make_xid_cell(x2), \
list_make_xid_cell(x3), list_make_xid_cell(x4), \
list_make_xid_cell(x5))
/*
* Locate the n'th cell (counting from 0) of the list.
* It is an assertion failure if there is no such cell.
@ -539,6 +558,7 @@ extern List *list_make5_impl(NodeTag t, ListCell datum1, ListCell datum2,
extern pg_nodiscard List *lappend(List *list, void *datum);
extern pg_nodiscard List *lappend_int(List *list, int datum);
extern pg_nodiscard List *lappend_oid(List *list, Oid datum);
extern pg_nodiscard List *lappend_xid(List *list, TransactionId datum);
extern pg_nodiscard List *list_insert_nth(List *list, int pos, void *datum);
extern pg_nodiscard List *list_insert_nth_int(List *list, int pos, int datum);
@ -557,6 +577,7 @@ extern bool list_member(const List *list, const void *datum);
extern bool list_member_ptr(const List *list, const void *datum);
extern bool list_member_int(const List *list, int datum);
extern bool list_member_oid(const List *list, Oid datum);
extern bool list_member_xid(const List *list, TransactionId datum);
extern pg_nodiscard List *list_delete(List *list, void *datum);
extern pg_nodiscard List *list_delete_ptr(List *list, void *datum);