From 484cb12cd038e5a3f3580df1efbe92826d78b837 Mon Sep 17 00:00:00 2001 From: Burak Yucesoy Date: Wed, 18 Jan 2017 12:00:56 +0200 Subject: [PATCH] Add LoadShardPlacement UDF This UDF returns a shard placement from cache given shard id and placement id. At the moment it iterates over all shard placements of given shard by ShardPlacementList and searches given placement id in that list, which is not a good solution performance-wise. However, currently, this function will be used only when there is a failed transaction. If a need arises we can optimize this function in the future. --- .../distributed/utils/metadata_cache.c | 42 +++++++++++++++++++ src/include/distributed/metadata_cache.h | 1 + 2 files changed, 43 insertions(+) diff --git a/src/backend/distributed/utils/metadata_cache.c b/src/backend/distributed/utils/metadata_cache.c index 21ff34447..9567ab560 100644 --- a/src/backend/distributed/utils/metadata_cache.c +++ b/src/backend/distributed/utils/metadata_cache.c @@ -245,6 +245,48 @@ LoadShardInterval(uint64 shardId) } +/* + * LoadShardPlacement returns the, cached, metadata about a shard placement. + * + * The return value is a copy of the cached ShardPlacement struct and may + * therefore be modified and/or freed. + */ +ShardPlacement * +LoadShardPlacement(uint64 shardId, uint64 placementId) +{ + ShardCacheEntry *shardEntry = NULL; + DistTableCacheEntry *tableEntry = NULL; + + ShardPlacement *placementArray = NULL; + int numberOfPlacements = 0; + + int i = 0; + + shardEntry = LookupShardCacheEntry(shardId); + tableEntry = shardEntry->tableEntry; + + /* the offset better be in a valid range */ + Assert(shardEntry->shardIndex < tableEntry->shardIntervalArrayLength); + + placementArray = tableEntry->arrayOfPlacementArrays[shardEntry->shardIndex]; + numberOfPlacements = tableEntry->arrayOfPlacementArrayLengths[shardEntry->shardIndex]; + + for (i = 0; i < numberOfPlacements; i++) + { + if (placementArray[i].placementId == placementId) + { + ShardPlacement *shardPlacement = CitusMakeNode(ShardPlacement); + CopyShardPlacement(&placementArray[i], shardPlacement); + + return shardPlacement; + } + } + + ereport(ERROR, (errmsg("could not find valid entry for shard placement " + UINT64_FORMAT, placementId))); +} + + /* * ShardPlacementList returns the list of placements for the given shard from * the cache. diff --git a/src/include/distributed/metadata_cache.h b/src/include/distributed/metadata_cache.h index 314002acc..abd1861c0 100644 --- a/src/include/distributed/metadata_cache.h +++ b/src/include/distributed/metadata_cache.h @@ -59,6 +59,7 @@ typedef struct extern bool IsDistributedTable(Oid relationId); extern List * DistributedTableList(void); extern ShardInterval * LoadShardInterval(uint64 shardId); +extern ShardPlacement * LoadShardPlacement(uint64 shardId, uint64 placementId); extern DistTableCacheEntry * DistributedTableCacheEntry(Oid distributedRelationId); extern int GetLocalGroupId(void); extern List * DistTableOidList(void);