Skip to content

Commit

Permalink
Refactored
Browse files Browse the repository at this point in the history
  • Loading branch information
JorgeCandeias committed Dec 9, 2024
1 parent d1c7184 commit 18473ad
Showing 1 changed file with 48 additions and 54 deletions.
102 changes: 48 additions & 54 deletions src/AdoNet/Orleans.GrainDirectory.AdoNet/PostgreSQL-GrainDirectory.sql
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
/*
Orleans Grain Directory.
This tables stores the location of all grains in the cluster.
This table stores the location of all grains in the cluster.
The rationale for this table is as follows:
The demands for this table are as follows:
1. The table will see rows inserted individually, as new grains are added.
2. The table will see rows deleted at random as grains are deactivated, without regard for order.
3. Insert/Delete churn is expected to be very high.
4. The GrainId is too large to be indexed by SQL Server.
Given the above, the table cannot be a clustered index.
Not only is the GrainId too large to index directly, the expected insert/delete churn would cause fragmentation to the point of rendering the directory unusable.
Therefore the design choice is to use a heap table with a non-clustered index on the stable hash of the grain key.
To address these demands, this table is implemented as a non-unique table with a hash index.
This index covers the hash of the grain id to allow for fast lookups.
Uniqueness is then guaranteed by careful use of locks on the hash index.
*/
CREATE TABLE OrleansGrainDirectory
(
Expand All @@ -39,27 +39,15 @@ CREATE TABLE OrleansGrainDirectory
CreatedOn TIMESTAMPTZ NOT NULL
);

/*
This index is a workaround for the GrainId being too large to index by SQL Server.
Instead we index a stable hash of the GrainId.
Collisions are possible yet handled by careful use of locks on this index.
*/
CREATE INDEX IX_OrleansGrainDirectory_Lookup
/* This turns the table into a CLUSTERED INDEX that allows duplication on the hash. */
CREATE INDEX IX_OrleansGrainDirectory
ON OrleansGrainDirectory
(
ClusterId ASC,
ProviderId ASC,
GrainIdHash ASC
)
INCLUDE
(
GrainId,
SiloAddress,
ActivationId,
CreatedOn
ClusterId,
ProviderId,
GrainIdHash
);

/* Registers a new grain activation */
/* Registers a new grain activation */
CREATE OR REPLACE FUNCTION RegisterGrainActivation(
_ClusterId VARCHAR(150),
Expand Down Expand Up @@ -87,47 +75,53 @@ BEGIN
-- this is required to prevent both duplication and deadlocks
LOCK TABLE OrleansGrainDirectory IN EXCLUSIVE MODE;

MERGE INTO OrleansGrainDirectory AS Target
USING (SELECT _ClusterId, _ProviderId, _GrainIdHash, _GrainId, _SiloAddress, _ActivationId, _Now) AS Source
ON
Target.ClusterId = Source._ClusterId
AND Target.ProviderId = Source._ProviderId
AND Target.GrainIdHash = Source._GrainIdHash
AND Target.GrainId = Source._GrainId
WHEN NOT MATCHED THEN
INSERT
(
ClusterId,
ProviderId,
GrainIdHash,
GrainId,
SiloAddress,
ActivationId,
CreatedOn
)
VALUES
(
Source._ClusterId,
Source._ProviderId,
Source._GrainIdHash,
Source._GrainId,
Source._SiloAddress,
Source._ActivationId,
Source._Now
);

RETURN QUERY
SELECT
ClusterId,
ProviderId,
GrainId,
SiloAddress,
ActivationId
FROM OrleansGrainDirectory
WHERE ClusterId = _ClusterId
FROM
OrleansGrainDirectory
WHERE
ClusterId = _ClusterId
AND ProviderId = _ProviderId
AND GrainIdHash = _GrainIdHash
AND GrainId = _GrainId;
AND GrainId = _GrainId
FOR UPDATE;

IF NOT FOUND THEN

RETURN QUERY
INSERT INTO OrleansGrainDirectory
(
ClusterId,
ProviderId,
GrainIdHash,
GrainId,
SiloAddress,
ActivationId,
CreatedOn
)
VALUES
(
_ClusterId,
_ProviderId,
_GrainIdHash,
_GrainId,
_SiloAddress,
_ActivationId,
_Now
)
RETURNING
ClusterId,
ProviderId,
GrainId,
SiloAddress,
ActivationId;

END IF;

END;
$$;
Expand Down

0 comments on commit 18473ad

Please sign in to comment.