example of foreach_(index|first) macro's

feature/foreach_index
Nils Dijk 2021-11-03 16:30:25 +01:00
parent 19f28eabae
commit 4c15e0fbd5
No known key found for this signature in database
GPG Key ID: CA1177EF9434F241
2 changed files with 31 additions and 7 deletions

View File

@ -921,7 +921,6 @@ ShardListInsertCommand(List *shardIntervalList)
"shardlength, groupid, placementid) AS (VALUES "); "shardlength, groupid, placementid) AS (VALUES ");
ShardInterval *shardInterval = NULL; ShardInterval *shardInterval = NULL;
bool isFirstValue = true;
foreach_ptr(shardInterval, shardIntervalList) foreach_ptr(shardInterval, shardIntervalList)
{ {
uint64 shardId = shardInterval->shardId; uint64 shardId = shardInterval->shardId;
@ -930,7 +929,7 @@ ShardListInsertCommand(List *shardIntervalList)
ShardPlacement *placement = NULL; ShardPlacement *placement = NULL;
foreach_ptr(placement, shardPlacementList) foreach_ptr(placement, shardPlacementList)
{ {
if (!isFirstValue) if (!foreach_first(shardInterval) || foreach_first(placement))
{ {
/* /*
* As long as this is not the first placement of the first shard, * As long as this is not the first placement of the first shard,
@ -938,7 +937,6 @@ ShardListInsertCommand(List *shardIntervalList)
*/ */
appendStringInfo(insertPlacementCommand, ", "); appendStringInfo(insertPlacementCommand, ", ");
} }
isFirstValue = false;
appendStringInfo(insertPlacementCommand, appendStringInfo(insertPlacementCommand,
"(%ld, %d, %ld, %d, %ld)", "(%ld, %d, %ld, %d, %ld)",

View File

@ -33,6 +33,13 @@ typedef struct ListCellAndListWrapper
ListCell *listCell; ListCell *listCell;
} ListCellAndListWrapper; } ListCellAndListWrapper;
typedef struct ListCellAndIndex
{
ListCell *listCell;
int index;
} ListCellAndIndex;
/* /*
* foreach_ptr - * foreach_ptr -
* a convenience macro which loops through a pointer list without needing a * a convenience macro which loops through a pointer list without needing a
@ -49,10 +56,13 @@ typedef struct ListCellAndListWrapper
* var is NULL. * var is NULL.
*/ */
#define foreach_ptr(var, l) \ #define foreach_ptr(var, l) \
for (ListCell *(var ## CellDoNotUse) = list_head(l); \ for (ListCellAndIndex(var ## InternalDoNotUse) = { list_head(l), 0 }; \
(var ## CellDoNotUse) != NULL && \ (var ## InternalDoNotUse).listCell != NULL && \
(((var) = lfirst(var ## CellDoNotUse)) || true); \ (((var) = lfirst((var ## InternalDoNotUse).listCell)) || true); \
var ## CellDoNotUse = lnext_compat(l, var ## CellDoNotUse)) (var ## InternalDoNotUse).listCell = lnext_compat(l, \
(var ## InternalDoNotUse). \
listCell), \
(var ## InternalDoNotUse).index ++)
/* /*
@ -113,6 +123,22 @@ typedef struct ListCellAndListWrapper
#define foreach_ptr_append(var, l) foreach_ptr(var, l) #define foreach_ptr_append(var, l) foreach_ptr(var, l)
#endif #endif
/*
* foreach_index
* when in _any_ kind foreach_* block, return the index of the iterator based on the
* name of the variable that captures the item from the list.
*/
#define foreach_index(var) ((var ## InternalDoNotUse).index)
/*
* foreach_first
* convenience on top of foreach_index that checks if it is the first loop
*/
#define foreach_first(var) ((foreach_index(var)) == 0)
/* utility functions declaration shared within this module */ /* utility functions declaration shared within this module */
extern List * SortList(List *pointerList, extern List * SortList(List *pointerList,
int (*ComparisonFunction)(const void *, const void *)); int (*ComparisonFunction)(const void *, const void *));