Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/indexer-agent/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@graphprotocol/indexer-agent",
"version": "0.25.0",
"version": "0.25.1",
"description": "Indexer agent",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
Expand Down Expand Up @@ -30,7 +30,7 @@
},
"dependencies": {
"@graphprotocol/common-ts": "3.0.1",
"@graphprotocol/indexer-common": "0.25.0",
"@graphprotocol/indexer-common": "0.25.1",
"@thi.ng/heaps": "^1.3.1",
"axios": "0.26.1",
"bs58": "5.0.0",
Expand Down
4 changes: 2 additions & 2 deletions packages/indexer-cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@graphprotocol/indexer-cli",
"version": "0.25.0",
"version": "0.25.1",
"description": "Indexer CLI for The Graph Network",
"main": "./dist/cli.js",
"files": [
Expand All @@ -27,7 +27,7 @@
},
"dependencies": {
"@graphprotocol/common-ts": "3.0.1",
"@graphprotocol/indexer-common": "0.25.0",
"@graphprotocol/indexer-common": "0.25.1",
"@iarna/toml": "2.2.5",
"@thi.ng/iterators": "5.1.74",
"@urql/core": "3.1.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/indexer-common/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@graphprotocol/indexer-common",
"version": "0.25.0",
"version": "0.25.1",
"description": "Common library for Graph Protocol indexer components",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
Expand Down
34 changes: 22 additions & 12 deletions packages/indexer-common/src/allocations/graph-tally-collector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,20 +236,30 @@ export class GraphTallyCollector {
})
this.logger.trace(`[TAPv2] RAW DATA`, { ravs, allocations })

const pendingRAVsToProcess = ravs
.map((rav) => {
const signedRav = rav.getSignedRAV()
return {
// Create an object for O(1) allocation lookups instead of O(n) Array.find()
// This optimizes performance from O(n²) to O(n) for large datasets
const allocationMap: { [key: string]: Allocation } = {}
for (let i = 0; i < allocations.length; i++) {
const allocation = allocations[i]
allocationMap[allocation.id.toLowerCase()] = allocation
}

const pendingRAVsToProcess: RavWithAllocation[] = []
for (let i = 0; i < ravs.length; i++) {
const rav = ravs[i]
const signedRav = rav.getSignedRAV()
const allocationId = toAddress(
collectionIdToAllocationId(signedRav.rav.collectionId),
).toLowerCase()
const allocation = allocationMap[allocationId] // O(1) lookup
if (allocation !== undefined) {
pendingRAVsToProcess.push({
rav: signedRav,
allocation: allocations.find(
(a) =>
a.id ===
toAddress(collectionIdToAllocationId(signedRav.rav.collectionId)),
),
allocation: allocation,
payer: rav.payer,
}
})
.filter((rav) => rav.allocation !== undefined) as RavWithAllocation[] // this is safe because we filter out undefined allocations
})
}
}
this.logger.trace(`[TAPv2] Pending RAVs to process`, {
pendingRAVsToProcess: pendingRAVsToProcess.length,
})
Expand Down
34 changes: 24 additions & 10 deletions packages/indexer-common/src/allocations/tap-collector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,18 +216,32 @@ export class TapCollector {
ravs: ravs.length,
allocations: allocations.length,
})
return ravs
.map((rav) => {
const signedRav = rav.getSignedRAV()
return {

// Create an object for O(1) allocation lookups instead of O(n) Array.find()
// This optimizes performance from O(n²) to O(n) for large datasets
const allocationMap: { [key: string]: Allocation } = {}
for (let i = 0; i < allocations.length; i++) {
const allocation = allocations[i]
allocationMap[allocation.id.toLowerCase()] = allocation
}

const results: RavWithAllocation[] = []
for (let i = 0; i < ravs.length; i++) {
const rav = ravs[i]
const signedRav = rav.getSignedRAV()
const allocationId = toAddress(
signedRav.rav.allocationId.toString(),
).toLowerCase()
const allocation = allocationMap[allocationId] // O(1) lookup
if (allocation !== undefined) {
results.push({
rav: signedRav,
allocation: allocations.find(
(a) => a.id === toAddress(signedRav.rav.allocationId.toString()),
),
allocation: allocation,
sender: rav.senderAddress,
}
})
.filter((rav) => rav.allocation !== undefined) as RavWithAllocation[] // this is safe because we filter out undefined allocations
})
}
}
return results
},
{
onError: (err) =>
Expand Down
11 changes: 9 additions & 2 deletions packages/indexer-common/src/indexer-management/allocations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
IndexingStatus,
isActionFailure,
isDeploymentWorthAllocatingTowards,
preprocessRules,
Network,
ReallocateAllocationResult,
SubgraphIdentifierType,
Expand Down Expand Up @@ -1791,8 +1792,14 @@ export class AllocationManager {
`SHOULD BE UNREACHABLE: No matching subgraphDeployment (${subgraphDeploymentID.ipfsHash}) found on the network`,
)
}
return isDeploymentWorthAllocatingTowards(logger, subgraphDeployment, indexingRules)
.toAllocate
// Use preprocessed rules for O(1) lookup
const { deploymentRulesMap, globalRule } = preprocessRules(indexingRules)
return isDeploymentWorthAllocatingTowards(
logger,
subgraphDeployment,
deploymentRulesMap,
globalRule,
).toAllocate
}

// Calculates the balance (GRT delta) of a single Action.
Expand Down
46 changes: 36 additions & 10 deletions packages/indexer-common/src/subgraphs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,30 @@ interface RuleMatch {
activationCriteria: ActivationCriteria
}

export interface PreprocessedRules {
deploymentRulesMap: { [key: string]: IndexingRuleAttributes }
globalRule: IndexingRuleAttributes | undefined
}

// Preprocess rules into a Map for O(1) lookups instead of O(n) Array.filter().find()
// This optimizes performance from O(n²) to O(n) when evaluating many deployments
export function preprocessRules(rules: IndexingRuleAttributes[]): PreprocessedRules {
const deploymentRulesMap: { [key: string]: IndexingRuleAttributes } = {}
let globalRule: IndexingRuleAttributes | undefined = undefined

for (let i = 0; i < rules.length; i++) {
const rule = rules[i]
if (rule.identifier === INDEXING_RULE_GLOBAL) {
globalRule = rule
} else if (rule.identifierType === SubgraphIdentifierType.DEPLOYMENT) {
const key = new SubgraphDeploymentID(rule.identifier).bytes32
deploymentRulesMap[key] = rule
}
}

return { deploymentRulesMap, globalRule }
}

export class AllocationDecision {
declare deployment: SubgraphDeploymentID
declare toAllocate: boolean
Expand Down Expand Up @@ -192,24 +216,26 @@ export function evaluateDeployments(
networkDeployments: SubgraphDeployment[],
rules: IndexingRuleAttributes[],
): AllocationDecision[] {
// Preprocess rules once for O(1) lookups instead of O(n) per deployment
const { deploymentRulesMap, globalRule } = preprocessRules(rules)
return networkDeployments.map((deployment) =>
isDeploymentWorthAllocatingTowards(logger, deployment, rules),
isDeploymentWorthAllocatingTowards(
logger,
deployment,
deploymentRulesMap,
globalRule,
),
)
}

export function isDeploymentWorthAllocatingTowards(
logger: Logger,
deployment: SubgraphDeployment,
rules: IndexingRuleAttributes[],
deploymentRulesMap: { [key: string]: IndexingRuleAttributes },
globalRule: IndexingRuleAttributes | undefined,
): AllocationDecision {
const globalRule = rules.find((rule) => rule.identifier === INDEXING_RULE_GLOBAL)
const deploymentRule =
rules
.filter((rule) => rule.identifierType == SubgraphIdentifierType.DEPLOYMENT)
.find(
(rule) =>
new SubgraphDeploymentID(rule.identifier).bytes32 === deployment.id.bytes32,
) || globalRule
// O(1) lookup using preprocessed rules map
const deploymentRule = deploymentRulesMap[deployment.id.bytes32] || globalRule

logger.trace('Evaluating whether subgraphDeployment is worth allocating towards', {
deployment,
Expand Down
Loading