@varity-labs/sdk 2.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +31 -0
- package/README.md +253 -0
- package/dist/analytics/index.d.ts +7 -0
- package/dist/analytics/index.d.ts.map +1 -0
- package/dist/analytics/index.js +6 -0
- package/dist/analytics/tracker.d.ts +128 -0
- package/dist/analytics/tracker.d.ts.map +1 -0
- package/dist/analytics/tracker.js +203 -0
- package/dist/blockchain/BlockchainService.d.ts +100 -0
- package/dist/blockchain/BlockchainService.d.ts.map +1 -0
- package/dist/blockchain/BlockchainService.js +188 -0
- package/dist/blockchain/NFTLicensingService.d.ts +69 -0
- package/dist/blockchain/NFTLicensingService.d.ts.map +1 -0
- package/dist/blockchain/NFTLicensingService.js +136 -0
- package/dist/blockchain/RevenueSplitService.d.ts +71 -0
- package/dist/blockchain/RevenueSplitService.d.ts.map +1 -0
- package/dist/blockchain/RevenueSplitService.js +111 -0
- package/dist/blockchain/index.d.ts +48 -0
- package/dist/blockchain/index.d.ts.map +1 -0
- package/dist/blockchain/index.js +46 -0
- package/dist/blockchain/types.d.ts +63 -0
- package/dist/blockchain/types.d.ts.map +1 -0
- package/dist/blockchain/types.js +6 -0
- package/dist/chains/arbitrum.d.ts +89 -0
- package/dist/chains/arbitrum.d.ts.map +1 -0
- package/dist/chains/arbitrum.js +134 -0
- package/dist/chains/base.d.ts +84 -0
- package/dist/chains/base.d.ts.map +1 -0
- package/dist/chains/base.js +131 -0
- package/dist/chains/index.d.ts +36 -0
- package/dist/chains/index.d.ts.map +1 -0
- package/dist/chains/index.js +32 -0
- package/dist/chains/registry.d.ts +113 -0
- package/dist/chains/registry.d.ts.map +1 -0
- package/dist/chains/registry.js +201 -0
- package/dist/chains/varityL3.d.ts +81 -0
- package/dist/chains/varityL3.d.ts.map +1 -0
- package/dist/chains/varityL3.js +125 -0
- package/dist/cli/commands/clone.d.ts +8 -0
- package/dist/cli/commands/clone.d.ts.map +1 -0
- package/dist/cli/commands/clone.js +391 -0
- package/dist/cli/commands/dev.d.ts +8 -0
- package/dist/cli/commands/dev.d.ts.map +1 -0
- package/dist/cli/commands/dev.js +40 -0
- package/dist/cli/commands/generate.d.ts +8 -0
- package/dist/cli/commands/generate.d.ts.map +1 -0
- package/dist/cli/commands/generate.js +303 -0
- package/dist/cli/commands/init.d.ts +8 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +317 -0
- package/dist/cli/commands/validate.d.ts +8 -0
- package/dist/cli/commands/validate.d.ts.map +1 -0
- package/dist/cli/commands/validate.js +69 -0
- package/dist/cli/index.d.ts +8 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +33 -0
- package/dist/cli/utils/logger.d.ts +17 -0
- package/dist/cli/utils/logger.d.ts.map +1 -0
- package/dist/cli/utils/logger.js +35 -0
- package/dist/cli/utils/prompts.d.ts +21 -0
- package/dist/cli/utils/prompts.d.ts.map +1 -0
- package/dist/cli/utils/prompts.js +103 -0
- package/dist/contracts/abis/iso/AccessControlRegistry.json +1468 -0
- package/dist/contracts/abis/iso/DataProofRegistry.json +797 -0
- package/dist/contracts/abis/iso/MerchantRegistry.json +1237 -0
- package/dist/contracts/abis/iso/RepPerformance.json +1351 -0
- package/dist/contracts/abis/iso/ResidualCalculator.json +1118 -0
- package/dist/contracts/abis/iso/TransactionVault.json +1588 -0
- package/dist/contracts/abis/iso/VarityWalletFactory.json +475 -0
- package/dist/contracts/addresses.d.ts +88 -0
- package/dist/contracts/addresses.d.ts.map +1 -0
- package/dist/contracts/addresses.js +94 -0
- package/dist/contracts/index.d.ts +7 -0
- package/dist/contracts/index.d.ts.map +1 -0
- package/dist/contracts/index.js +6 -0
- package/dist/core/VaritySDK.d.ts +177 -0
- package/dist/core/VaritySDK.d.ts.map +1 -0
- package/dist/core/VaritySDK.js +325 -0
- package/dist/core/config.d.ts +120 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +187 -0
- package/dist/core/credentials-proxy.d.ts +157 -0
- package/dist/core/credentials-proxy.d.ts.map +1 -0
- package/dist/core/credentials-proxy.js +345 -0
- package/dist/core/credentials.d.ts +219 -0
- package/dist/core/credentials.d.ts.map +1 -0
- package/dist/core/credentials.js +345 -0
- package/dist/core/template-loader.d.ts +15 -0
- package/dist/core/template-loader.d.ts.map +1 -0
- package/dist/core/template-loader.js +380 -0
- package/dist/core/template.d.ts +321 -0
- package/dist/core/template.d.ts.map +1 -0
- package/dist/core/template.js +189 -0
- package/dist/core/types.d.ts +572 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +52 -0
- package/dist/dev/dev-server.d.ts +16 -0
- package/dist/dev/dev-server.d.ts.map +1 -0
- package/dist/dev/dev-server.js +119 -0
- package/dist/generators/contracts/generator.d.ts +21 -0
- package/dist/generators/contracts/generator.d.ts.map +1 -0
- package/dist/generators/contracts/generator.js +252 -0
- package/dist/generators/tests/generator.d.ts +20 -0
- package/dist/generators/tests/generator.d.ts.map +1 -0
- package/dist/generators/tests/generator.js +375 -0
- package/dist/generators/types/generator.d.ts +19 -0
- package/dist/generators/types/generator.d.ts.map +1 -0
- package/dist/generators/types/generator.js +165 -0
- package/dist/generators/ui/component-generator.d.ts +20 -0
- package/dist/generators/ui/component-generator.d.ts.map +1 -0
- package/dist/generators/ui/component-generator.js +749 -0
- package/dist/generators/ui/dashboard-generator.d.ts +20 -0
- package/dist/generators/ui/dashboard-generator.d.ts.map +1 -0
- package/dist/generators/ui/dashboard-generator.js +349 -0
- package/dist/index.d.ts +61 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +74 -0
- package/dist/modules/analytics/AnalyticsModule.d.ts +349 -0
- package/dist/modules/analytics/AnalyticsModule.d.ts.map +1 -0
- package/dist/modules/analytics/AnalyticsModule.js +274 -0
- package/dist/modules/analytics/index.d.ts +3 -0
- package/dist/modules/analytics/index.d.ts.map +1 -0
- package/dist/modules/analytics/index.js +1 -0
- package/dist/modules/auth/AccessKeyModule.d.ts +189 -0
- package/dist/modules/auth/AccessKeyModule.d.ts.map +1 -0
- package/dist/modules/auth/AccessKeyModule.js +322 -0
- package/dist/modules/auth/AuthModule.d.ts +133 -0
- package/dist/modules/auth/AuthModule.d.ts.map +1 -0
- package/dist/modules/auth/AuthModule.js +214 -0
- package/dist/modules/auth/index.d.ts +8 -0
- package/dist/modules/auth/index.d.ts.map +1 -0
- package/dist/modules/auth/index.js +6 -0
- package/dist/modules/cache/CacheModule.d.ts +279 -0
- package/dist/modules/cache/CacheModule.d.ts.map +1 -0
- package/dist/modules/cache/CacheModule.js +493 -0
- package/dist/modules/cache/index.d.ts +3 -0
- package/dist/modules/cache/index.d.ts.map +1 -0
- package/dist/modules/cache/index.js +1 -0
- package/dist/modules/compute/ComputeModule.d.ts +226 -0
- package/dist/modules/compute/ComputeModule.d.ts.map +1 -0
- package/dist/modules/compute/ComputeModule.js +379 -0
- package/dist/modules/compute/index.d.ts +6 -0
- package/dist/modules/compute/index.d.ts.map +1 -0
- package/dist/modules/compute/index.js +4 -0
- package/dist/modules/contracts/ContractsModule.d.ts +164 -0
- package/dist/modules/contracts/ContractsModule.d.ts.map +1 -0
- package/dist/modules/contracts/ContractsModule.js +242 -0
- package/dist/modules/contracts/index.d.ts +6 -0
- package/dist/modules/contracts/index.d.ts.map +1 -0
- package/dist/modules/contracts/index.js +4 -0
- package/dist/modules/export/ExportModule.d.ts +346 -0
- package/dist/modules/export/ExportModule.d.ts.map +1 -0
- package/dist/modules/export/ExportModule.js +432 -0
- package/dist/modules/export/index.d.ts +3 -0
- package/dist/modules/export/index.d.ts.map +1 -0
- package/dist/modules/export/index.js +1 -0
- package/dist/modules/forecasting/ForecastingModule.d.ts +579 -0
- package/dist/modules/forecasting/ForecastingModule.d.ts.map +1 -0
- package/dist/modules/forecasting/ForecastingModule.js +310 -0
- package/dist/modules/forecasting/index.d.ts +3 -0
- package/dist/modules/forecasting/index.d.ts.map +1 -0
- package/dist/modules/forecasting/index.js +1 -0
- package/dist/modules/monitoring/MonitoringModule.d.ts +359 -0
- package/dist/modules/monitoring/MonitoringModule.d.ts.map +1 -0
- package/dist/modules/monitoring/MonitoringModule.js +483 -0
- package/dist/modules/monitoring/index.d.ts +3 -0
- package/dist/modules/monitoring/index.d.ts.map +1 -0
- package/dist/modules/monitoring/index.js +1 -0
- package/dist/modules/notifications/NotificationsModule.d.ts +336 -0
- package/dist/modules/notifications/NotificationsModule.d.ts.map +1 -0
- package/dist/modules/notifications/NotificationsModule.js +418 -0
- package/dist/modules/notifications/index.d.ts +3 -0
- package/dist/modules/notifications/index.d.ts.map +1 -0
- package/dist/modules/notifications/index.js +1 -0
- package/dist/modules/oracle/OracleModule.d.ts +110 -0
- package/dist/modules/oracle/OracleModule.d.ts.map +1 -0
- package/dist/modules/oracle/OracleModule.js +151 -0
- package/dist/modules/oracle/index.d.ts +6 -0
- package/dist/modules/oracle/index.d.ts.map +1 -0
- package/dist/modules/oracle/index.js +4 -0
- package/dist/modules/storage/S3Module.d.ts +377 -0
- package/dist/modules/storage/S3Module.d.ts.map +1 -0
- package/dist/modules/storage/S3Module.js +680 -0
- package/dist/modules/storage/StorageModule.d.ts +157 -0
- package/dist/modules/storage/StorageModule.d.ts.map +1 -0
- package/dist/modules/storage/StorageModule.js +302 -0
- package/dist/modules/storage/adapters/AdapterFactory.d.ts +100 -0
- package/dist/modules/storage/adapters/AdapterFactory.d.ts.map +1 -0
- package/dist/modules/storage/adapters/AdapterFactory.js +209 -0
- package/dist/modules/storage/adapters/FilecoinAdapter.d.ts +94 -0
- package/dist/modules/storage/adapters/FilecoinAdapter.d.ts.map +1 -0
- package/dist/modules/storage/adapters/FilecoinAdapter.js +263 -0
- package/dist/modules/storage/adapters/IStorageAdapter.d.ts +287 -0
- package/dist/modules/storage/adapters/IStorageAdapter.d.ts.map +1 -0
- package/dist/modules/storage/adapters/IStorageAdapter.js +81 -0
- package/dist/modules/storage/adapters/MultiTierAdapter.d.ts +187 -0
- package/dist/modules/storage/adapters/MultiTierAdapter.d.ts.map +1 -0
- package/dist/modules/storage/adapters/MultiTierAdapter.js +430 -0
- package/dist/modules/storage/adapters/index.d.ts +12 -0
- package/dist/modules/storage/adapters/index.d.ts.map +1 -0
- package/dist/modules/storage/adapters/index.js +12 -0
- package/dist/modules/storage/index.d.ts +16 -0
- package/dist/modules/storage/index.d.ts.map +1 -0
- package/dist/modules/storage/index.js +15 -0
- package/dist/modules/storage/tiering/AccessAnalyzer.d.ts +227 -0
- package/dist/modules/storage/tiering/AccessAnalyzer.d.ts.map +1 -0
- package/dist/modules/storage/tiering/AccessAnalyzer.js +367 -0
- package/dist/modules/storage/tiering/CostOptimizer.d.ts +248 -0
- package/dist/modules/storage/tiering/CostOptimizer.d.ts.map +1 -0
- package/dist/modules/storage/tiering/CostOptimizer.js +356 -0
- package/dist/modules/storage/tiering/MetadataStore.d.ts +287 -0
- package/dist/modules/storage/tiering/MetadataStore.d.ts.map +1 -0
- package/dist/modules/storage/tiering/MetadataStore.js +535 -0
- package/dist/modules/storage/tiering/TieringEngine.d.ts +237 -0
- package/dist/modules/storage/tiering/TieringEngine.d.ts.map +1 -0
- package/dist/modules/storage/tiering/TieringEngine.js +419 -0
- package/dist/modules/storage/tiering/example.d.ts +8 -0
- package/dist/modules/storage/tiering/example.d.ts.map +1 -0
- package/dist/modules/storage/tiering/example.js +250 -0
- package/dist/modules/storage/tiering/index.d.ts +17 -0
- package/dist/modules/storage/tiering/index.d.ts.map +1 -0
- package/dist/modules/storage/tiering/index.js +13 -0
- package/dist/modules/webhooks/WebhooksModule.d.ts +476 -0
- package/dist/modules/webhooks/WebhooksModule.d.ts.map +1 -0
- package/dist/modules/webhooks/WebhooksModule.js +359 -0
- package/dist/modules/webhooks/index.d.ts +3 -0
- package/dist/modules/webhooks/index.d.ts.map +1 -0
- package/dist/modules/webhooks/index.js +1 -0
- package/dist/modules/zk/ZKModule.d.ts +153 -0
- package/dist/modules/zk/ZKModule.d.ts.map +1 -0
- package/dist/modules/zk/ZKModule.js +262 -0
- package/dist/modules/zk/index.d.ts +7 -0
- package/dist/modules/zk/index.d.ts.map +1 -0
- package/dist/modules/zk/index.js +4 -0
- package/dist/thirdweb/BridgeClient.d.ts +228 -0
- package/dist/thirdweb/BridgeClient.d.ts.map +1 -0
- package/dist/thirdweb/BridgeClient.js +160 -0
- package/dist/thirdweb/EngineClient.d.ts +396 -0
- package/dist/thirdweb/EngineClient.d.ts.map +1 -0
- package/dist/thirdweb/EngineClient.js +386 -0
- package/dist/thirdweb/GatewayClient.d.ts +190 -0
- package/dist/thirdweb/GatewayClient.d.ts.map +1 -0
- package/dist/thirdweb/GatewayClient.js +257 -0
- package/dist/thirdweb/NebulaClient.d.ts +292 -0
- package/dist/thirdweb/NebulaClient.d.ts.map +1 -0
- package/dist/thirdweb/NebulaClient.js +180 -0
- package/dist/thirdweb/StorageClient.d.ts +445 -0
- package/dist/thirdweb/StorageClient.d.ts.map +1 -0
- package/dist/thirdweb/StorageClient.js +405 -0
- package/dist/thirdweb/ThirdwebWrapper.d.ts +236 -0
- package/dist/thirdweb/ThirdwebWrapper.d.ts.map +1 -0
- package/dist/thirdweb/ThirdwebWrapper.js +332 -0
- package/dist/thirdweb/index.d.ts +21 -0
- package/dist/thirdweb/index.d.ts.map +1 -0
- package/dist/thirdweb/index.js +28 -0
- package/dist/thirdweb/varity-chain.d.ts +48 -0
- package/dist/thirdweb/varity-chain.d.ts.map +1 -0
- package/dist/thirdweb/varity-chain.js +64 -0
- package/dist/thirdweb/x402Client.d.ts +319 -0
- package/dist/thirdweb/x402Client.d.ts.map +1 -0
- package/dist/thirdweb/x402Client.js +223 -0
- package/dist/tracking/gasTracker.d.ts +158 -0
- package/dist/tracking/gasTracker.d.ts.map +1 -0
- package/dist/tracking/gasTracker.js +227 -0
- package/dist/tracking/index.d.ts +10 -0
- package/dist/tracking/index.d.ts.map +1 -0
- package/dist/tracking/index.js +8 -0
- package/dist/tracking/types.d.ts +327 -0
- package/dist/tracking/types.d.ts.map +1 -0
- package/dist/tracking/types.js +8 -0
- package/dist/ui/components/ChartWidget.d.ts +36 -0
- package/dist/ui/components/ChartWidget.d.ts.map +1 -0
- package/dist/ui/components/ChartWidget.js +82 -0
- package/dist/ui/components/DashboardLayout.d.ts +41 -0
- package/dist/ui/components/DashboardLayout.d.ts.map +1 -0
- package/dist/ui/components/DashboardLayout.js +102 -0
- package/dist/ui/components/DataTable.d.ts +49 -0
- package/dist/ui/components/DataTable.d.ts.map +1 -0
- package/dist/ui/components/DataTable.js +96 -0
- package/dist/ui/components/EntityForm.d.ts +60 -0
- package/dist/ui/components/EntityForm.d.ts.map +1 -0
- package/dist/ui/components/EntityForm.js +182 -0
- package/dist/ui/components/KPICard.d.ts +29 -0
- package/dist/ui/components/KPICard.d.ts.map +1 -0
- package/dist/ui/components/KPICard.js +61 -0
- package/dist/ui/components/Modal.d.ts +34 -0
- package/dist/ui/components/Modal.d.ts.map +1 -0
- package/dist/ui/components/Modal.js +30 -0
- package/dist/ui/components/index.d.ts +18 -0
- package/dist/ui/components/index.d.ts.map +1 -0
- package/dist/ui/components/index.js +11 -0
- package/dist/validation/template-validator.d.ts +25 -0
- package/dist/validation/template-validator.d.ts.map +1 -0
- package/dist/validation/template-validator.js +305 -0
- package/package.json +102 -0
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Varity SDK - Tiering Engine
|
|
3
|
+
*
|
|
4
|
+
* Advanced tiering engine for intelligent storage tier management.
|
|
5
|
+
* Evaluates access patterns, cost optimization, and performance requirements
|
|
6
|
+
* to automatically promote or demote objects between storage tiers.
|
|
7
|
+
*
|
|
8
|
+
* Features:
|
|
9
|
+
* - Rule-based tier evaluation
|
|
10
|
+
* - Scheduled background tiering cycles
|
|
11
|
+
* - Cost-aware decision making
|
|
12
|
+
* - Performance optimization
|
|
13
|
+
* - Configurable policies
|
|
14
|
+
*
|
|
15
|
+
* @packageDocumentation
|
|
16
|
+
*/
|
|
17
|
+
import { StorageTier, TieringPolicy, type TieringRule, type AccessPattern } from '@varity-labs/types';
|
|
18
|
+
/**
|
|
19
|
+
* Metadata tracked for tiering decisions
|
|
20
|
+
*/
|
|
21
|
+
export interface TieringMetadata {
|
|
22
|
+
/** Object identifier */
|
|
23
|
+
identifier: string;
|
|
24
|
+
/** Current storage tier */
|
|
25
|
+
tier: StorageTier;
|
|
26
|
+
/** Creation timestamp */
|
|
27
|
+
createdAt: Date;
|
|
28
|
+
/** Last accessed timestamp */
|
|
29
|
+
lastAccessed: Date;
|
|
30
|
+
/** Total access count */
|
|
31
|
+
accessCount: number;
|
|
32
|
+
/** Object size in bytes */
|
|
33
|
+
size: number;
|
|
34
|
+
/** Custom tags */
|
|
35
|
+
tags?: Record<string, string>;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Decision result from tiering evaluation
|
|
39
|
+
*/
|
|
40
|
+
export interface TieringDecision {
|
|
41
|
+
/** Whether to perform a tier change */
|
|
42
|
+
shouldChange: boolean;
|
|
43
|
+
/** Current tier */
|
|
44
|
+
currentTier: StorageTier;
|
|
45
|
+
/** Recommended target tier */
|
|
46
|
+
targetTier: StorageTier;
|
|
47
|
+
/** Reason for decision */
|
|
48
|
+
reason: string;
|
|
49
|
+
/** Estimated cost impact (positive = savings, negative = increase) */
|
|
50
|
+
costImpact: number;
|
|
51
|
+
/** Confidence score (0-1) */
|
|
52
|
+
confidence: number;
|
|
53
|
+
/** Rules that matched */
|
|
54
|
+
matchedRules: string[];
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Result of a tiering cycle execution
|
|
58
|
+
*/
|
|
59
|
+
export interface TieringCycleResult {
|
|
60
|
+
/** Cycle start timestamp */
|
|
61
|
+
startTime: Date;
|
|
62
|
+
/** Cycle end timestamp */
|
|
63
|
+
endTime: Date;
|
|
64
|
+
/** Total duration in milliseconds */
|
|
65
|
+
durationMs: number;
|
|
66
|
+
/** Objects evaluated */
|
|
67
|
+
objectsEvaluated: number;
|
|
68
|
+
/** Objects promoted to hotter tiers */
|
|
69
|
+
objectsPromoted: number;
|
|
70
|
+
/** Objects demoted to colder tiers */
|
|
71
|
+
objectsDemoted: number;
|
|
72
|
+
/** Total cost savings estimated (USD/month) */
|
|
73
|
+
estimatedMonthlySavings: number;
|
|
74
|
+
/** Errors encountered */
|
|
75
|
+
errors: TieringError[];
|
|
76
|
+
/** Summary statistics */
|
|
77
|
+
statistics: TieringCycleStats;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Statistics from a tiering cycle
|
|
81
|
+
*/
|
|
82
|
+
export interface TieringCycleStats {
|
|
83
|
+
/** Objects by tier before cycle */
|
|
84
|
+
tierDistributionBefore: Record<StorageTier, number>;
|
|
85
|
+
/** Objects by tier after cycle */
|
|
86
|
+
tierDistributionAfter: Record<StorageTier, number>;
|
|
87
|
+
/** Total data moved (bytes) */
|
|
88
|
+
dataMoved: number;
|
|
89
|
+
/** Average decision confidence */
|
|
90
|
+
avgConfidence: number;
|
|
91
|
+
/** Rules applied count */
|
|
92
|
+
rulesApplied: Record<string, number>;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Error encountered during tiering
|
|
96
|
+
*/
|
|
97
|
+
export interface TieringError {
|
|
98
|
+
/** Object identifier */
|
|
99
|
+
identifier: string;
|
|
100
|
+
/** Error message */
|
|
101
|
+
error: string;
|
|
102
|
+
/** Error timestamp */
|
|
103
|
+
timestamp: Date;
|
|
104
|
+
/** Operation that failed */
|
|
105
|
+
operation: 'evaluate' | 'promote' | 'demote';
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Tiering engine configuration
|
|
109
|
+
*/
|
|
110
|
+
export interface TieringEngineConfig {
|
|
111
|
+
/** Tiering policy */
|
|
112
|
+
policy: TieringPolicy;
|
|
113
|
+
/** Custom tiering rules */
|
|
114
|
+
rules: TieringRule[];
|
|
115
|
+
/** Enable dry-run mode (no actual changes) */
|
|
116
|
+
dryRun?: boolean;
|
|
117
|
+
/** Minimum confidence threshold for tier changes */
|
|
118
|
+
minConfidence?: number;
|
|
119
|
+
/** Cost per GB per month for each tier */
|
|
120
|
+
tierCosts: Record<StorageTier, number>;
|
|
121
|
+
/** Maximum objects to process per cycle */
|
|
122
|
+
maxObjectsPerCycle?: number;
|
|
123
|
+
/** Enable parallel processing */
|
|
124
|
+
parallel?: boolean;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Advanced tiering engine for intelligent storage optimization
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* ```typescript
|
|
131
|
+
* const engine = new TieringEngine({
|
|
132
|
+
* policy: TieringPolicy.COST_OPTIMIZED,
|
|
133
|
+
* rules: [
|
|
134
|
+
* {
|
|
135
|
+
* name: 'demote-old-cold-files',
|
|
136
|
+
* condition: { type: 'age', operator: 'gt', value: 90, unit: 'days' },
|
|
137
|
+
* action: { moveTo: StorageTier.GLACIER }
|
|
138
|
+
* }
|
|
139
|
+
* ],
|
|
140
|
+
* tierCosts: {
|
|
141
|
+
* [StorageTier.HOT]: 0.023,
|
|
142
|
+
* [StorageTier.WARM]: 0.012,
|
|
143
|
+
* [StorageTier.COLD]: 0.004,
|
|
144
|
+
* [StorageTier.GLACIER]: 0.001
|
|
145
|
+
* }
|
|
146
|
+
* })
|
|
147
|
+
*
|
|
148
|
+
* const decision = await engine.evaluateObject('obj-123', metadata)
|
|
149
|
+
* if (decision.shouldChange) {
|
|
150
|
+
* console.log(`Move to ${decision.targetTier}: ${decision.reason}`)
|
|
151
|
+
* }
|
|
152
|
+
* ```
|
|
153
|
+
*/
|
|
154
|
+
export declare class TieringEngine {
|
|
155
|
+
private config;
|
|
156
|
+
private cycleInProgress;
|
|
157
|
+
private lastCycleTime;
|
|
158
|
+
constructor(config: TieringEngineConfig);
|
|
159
|
+
/**
|
|
160
|
+
* Evaluate a single object for tier placement
|
|
161
|
+
*
|
|
162
|
+
* @param identifier - Object identifier
|
|
163
|
+
* @param metadata - Object metadata
|
|
164
|
+
* @param accessPattern - Optional access pattern analytics
|
|
165
|
+
* @returns Tiering decision
|
|
166
|
+
*/
|
|
167
|
+
evaluateObject(identifier: string, metadata: TieringMetadata, accessPattern?: AccessPattern): Promise<TieringDecision>;
|
|
168
|
+
/**
|
|
169
|
+
* Run a complete tiering cycle across all objects
|
|
170
|
+
*
|
|
171
|
+
* @param metadataList - List of all object metadata to evaluate
|
|
172
|
+
* @param onProgress - Optional progress callback
|
|
173
|
+
* @returns Cycle result with statistics
|
|
174
|
+
*/
|
|
175
|
+
runTieringCycle(metadataList: TieringMetadata[], onProgress?: (current: number, total: number) => void): Promise<TieringCycleResult>;
|
|
176
|
+
/**
|
|
177
|
+
* Get current configuration
|
|
178
|
+
*/
|
|
179
|
+
getConfig(): TieringEngineConfig;
|
|
180
|
+
/**
|
|
181
|
+
* Update configuration
|
|
182
|
+
*/
|
|
183
|
+
updateConfig(updates: Partial<TieringEngineConfig>): void;
|
|
184
|
+
/**
|
|
185
|
+
* Get last cycle time
|
|
186
|
+
*/
|
|
187
|
+
getLastCycleTime(): Date | null;
|
|
188
|
+
/**
|
|
189
|
+
* Check if cycle is in progress
|
|
190
|
+
*/
|
|
191
|
+
isCycleInProgress(): boolean;
|
|
192
|
+
/**
|
|
193
|
+
* Evaluate a tiering condition
|
|
194
|
+
*/
|
|
195
|
+
private evaluateCondition;
|
|
196
|
+
/**
|
|
197
|
+
* Compare values based on operator
|
|
198
|
+
*/
|
|
199
|
+
private compareValues;
|
|
200
|
+
/**
|
|
201
|
+
* Create a tiering decision
|
|
202
|
+
*/
|
|
203
|
+
private createDecision;
|
|
204
|
+
/**
|
|
205
|
+
* Evaluate by policy when no rules match
|
|
206
|
+
*/
|
|
207
|
+
private evaluateByPolicy;
|
|
208
|
+
/**
|
|
209
|
+
* Cost-optimized tier evaluation
|
|
210
|
+
*/
|
|
211
|
+
private evaluateCostOptimized;
|
|
212
|
+
/**
|
|
213
|
+
* Access-based tier evaluation
|
|
214
|
+
*/
|
|
215
|
+
private evaluateAccessBased;
|
|
216
|
+
/**
|
|
217
|
+
* Time-based tier evaluation
|
|
218
|
+
*/
|
|
219
|
+
private evaluateTimeBased;
|
|
220
|
+
/**
|
|
221
|
+
* Size-based tier evaluation
|
|
222
|
+
*/
|
|
223
|
+
private evaluateSizeBased;
|
|
224
|
+
/**
|
|
225
|
+
* Calculate monthly cost for tier and size
|
|
226
|
+
*/
|
|
227
|
+
private calculateMonthlyCost;
|
|
228
|
+
/**
|
|
229
|
+
* Check if tier change is a promotion (to hotter tier)
|
|
230
|
+
*/
|
|
231
|
+
private isPromotion;
|
|
232
|
+
/**
|
|
233
|
+
* Get tier distribution from metadata list
|
|
234
|
+
*/
|
|
235
|
+
private getTierDistribution;
|
|
236
|
+
}
|
|
237
|
+
//# sourceMappingURL=TieringEngine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TieringEngine.d.ts","sourceRoot":"","sources":["../../../../src/modules/storage/tiering/TieringEngine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EACL,WAAW,EACX,aAAa,EACb,KAAK,WAAW,EAGhB,KAAK,aAAa,EACnB,MAAM,oBAAoB,CAAA;AAE3B;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,wBAAwB;IACxB,UAAU,EAAE,MAAM,CAAA;IAClB,2BAA2B;IAC3B,IAAI,EAAE,WAAW,CAAA;IACjB,yBAAyB;IACzB,SAAS,EAAE,IAAI,CAAA;IACf,8BAA8B;IAC9B,YAAY,EAAE,IAAI,CAAA;IAClB,yBAAyB;IACzB,WAAW,EAAE,MAAM,CAAA;IACnB,2BAA2B;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,kBAAkB;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,uCAAuC;IACvC,YAAY,EAAE,OAAO,CAAA;IACrB,mBAAmB;IACnB,WAAW,EAAE,WAAW,CAAA;IACxB,8BAA8B;IAC9B,UAAU,EAAE,WAAW,CAAA;IACvB,0BAA0B;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,sEAAsE;IACtE,UAAU,EAAE,MAAM,CAAA;IAClB,6BAA6B;IAC7B,UAAU,EAAE,MAAM,CAAA;IAClB,yBAAyB;IACzB,YAAY,EAAE,MAAM,EAAE,CAAA;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,4BAA4B;IAC5B,SAAS,EAAE,IAAI,CAAA;IACf,0BAA0B;IAC1B,OAAO,EAAE,IAAI,CAAA;IACb,qCAAqC;IACrC,UAAU,EAAE,MAAM,CAAA;IAClB,wBAAwB;IACxB,gBAAgB,EAAE,MAAM,CAAA;IACxB,uCAAuC;IACvC,eAAe,EAAE,MAAM,CAAA;IACvB,sCAAsC;IACtC,cAAc,EAAE,MAAM,CAAA;IACtB,+CAA+C;IAC/C,uBAAuB,EAAE,MAAM,CAAA;IAC/B,yBAAyB;IACzB,MAAM,EAAE,YAAY,EAAE,CAAA;IACtB,yBAAyB;IACzB,UAAU,EAAE,iBAAiB,CAAA;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,mCAAmC;IACnC,sBAAsB,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAA;IACnD,kCAAkC;IAClC,qBAAqB,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAA;IAClD,+BAA+B;IAC/B,SAAS,EAAE,MAAM,CAAA;IACjB,kCAAkC;IAClC,aAAa,EAAE,MAAM,CAAA;IACrB,0BAA0B;IAC1B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACrC;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,wBAAwB;IACxB,UAAU,EAAE,MAAM,CAAA;IAClB,oBAAoB;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,sBAAsB;IACtB,SAAS,EAAE,IAAI,CAAA;IACf,4BAA4B;IAC5B,SAAS,EAAE,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAA;CAC7C;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,qBAAqB;IACrB,MAAM,EAAE,aAAa,CAAA;IACrB,2BAA2B;IAC3B,KAAK,EAAE,WAAW,EAAE,CAAA;IACpB,8CAA8C;IAC9C,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,oDAAoD;IACpD,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,0CAA0C;IAC1C,SAAS,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAA;IACtC,2CAA2C;IAC3C,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,iCAAiC;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,eAAe,CAAiB;IACxC,OAAO,CAAC,aAAa,CAAoB;gBAE7B,MAAM,EAAE,mBAAmB;IAavC;;;;;;;OAOG;IACG,cAAc,CAClB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,eAAe,EACzB,aAAa,CAAC,EAAE,aAAa,GAC5B,OAAO,CAAC,eAAe,CAAC;IA2C3B;;;;;;OAMG;IACG,eAAe,CACnB,YAAY,EAAE,eAAe,EAAE,EAC/B,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,GACpD,OAAO,CAAC,kBAAkB,CAAC;IAwH9B;;OAEG;IACH,SAAS,IAAI,mBAAmB;IAIhC;;OAEG;IACH,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,mBAAmB,CAAC,GAAG,IAAI;IASzD;;OAEG;IACH,gBAAgB,IAAI,IAAI,GAAG,IAAI;IAI/B;;OAEG;IACH,iBAAiB,IAAI,OAAO;IAQ5B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAwCzB;;OAEG;IACH,OAAO,CAAC,aAAa;IAgBrB;;OAEG;IACH,OAAO,CAAC,cAAc;IA2BtB;;OAEG;YACW,gBAAgB;IA2B9B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAyB7B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAoB3B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAYzB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAgBzB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAM5B;;OAEG;IACH,OAAO,CAAC,WAAW;IAUnB;;OAEG;IACH,OAAO,CAAC,mBAAmB;CAc5B"}
|
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Varity SDK - Tiering Engine
|
|
3
|
+
*
|
|
4
|
+
* Advanced tiering engine for intelligent storage tier management.
|
|
5
|
+
* Evaluates access patterns, cost optimization, and performance requirements
|
|
6
|
+
* to automatically promote or demote objects between storage tiers.
|
|
7
|
+
*
|
|
8
|
+
* Features:
|
|
9
|
+
* - Rule-based tier evaluation
|
|
10
|
+
* - Scheduled background tiering cycles
|
|
11
|
+
* - Cost-aware decision making
|
|
12
|
+
* - Performance optimization
|
|
13
|
+
* - Configurable policies
|
|
14
|
+
*
|
|
15
|
+
* @packageDocumentation
|
|
16
|
+
*/
|
|
17
|
+
import { StorageTier, TieringPolicy } from '@varity-labs/types';
|
|
18
|
+
/**
|
|
19
|
+
* Advanced tiering engine for intelligent storage optimization
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* const engine = new TieringEngine({
|
|
24
|
+
* policy: TieringPolicy.COST_OPTIMIZED,
|
|
25
|
+
* rules: [
|
|
26
|
+
* {
|
|
27
|
+
* name: 'demote-old-cold-files',
|
|
28
|
+
* condition: { type: 'age', operator: 'gt', value: 90, unit: 'days' },
|
|
29
|
+
* action: { moveTo: StorageTier.GLACIER }
|
|
30
|
+
* }
|
|
31
|
+
* ],
|
|
32
|
+
* tierCosts: {
|
|
33
|
+
* [StorageTier.HOT]: 0.023,
|
|
34
|
+
* [StorageTier.WARM]: 0.012,
|
|
35
|
+
* [StorageTier.COLD]: 0.004,
|
|
36
|
+
* [StorageTier.GLACIER]: 0.001
|
|
37
|
+
* }
|
|
38
|
+
* })
|
|
39
|
+
*
|
|
40
|
+
* const decision = await engine.evaluateObject('obj-123', metadata)
|
|
41
|
+
* if (decision.shouldChange) {
|
|
42
|
+
* console.log(`Move to ${decision.targetTier}: ${decision.reason}`)
|
|
43
|
+
* }
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export class TieringEngine {
|
|
47
|
+
constructor(config) {
|
|
48
|
+
this.cycleInProgress = false;
|
|
49
|
+
this.lastCycleTime = null;
|
|
50
|
+
this.config = {
|
|
51
|
+
...config,
|
|
52
|
+
dryRun: config.dryRun ?? false,
|
|
53
|
+
minConfidence: config.minConfidence ?? 0.7,
|
|
54
|
+
maxObjectsPerCycle: config.maxObjectsPerCycle ?? 10000,
|
|
55
|
+
parallel: config.parallel ?? true
|
|
56
|
+
};
|
|
57
|
+
// Sort rules by priority
|
|
58
|
+
this.config.rules.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Evaluate a single object for tier placement
|
|
62
|
+
*
|
|
63
|
+
* @param identifier - Object identifier
|
|
64
|
+
* @param metadata - Object metadata
|
|
65
|
+
* @param accessPattern - Optional access pattern analytics
|
|
66
|
+
* @returns Tiering decision
|
|
67
|
+
*/
|
|
68
|
+
async evaluateObject(identifier, metadata, accessPattern) {
|
|
69
|
+
const matchedRules = [];
|
|
70
|
+
let bestDecision = {
|
|
71
|
+
shouldChange: false,
|
|
72
|
+
currentTier: metadata.tier,
|
|
73
|
+
targetTier: metadata.tier,
|
|
74
|
+
reason: 'No tier change needed',
|
|
75
|
+
costImpact: 0,
|
|
76
|
+
confidence: 1.0,
|
|
77
|
+
matchedRules: []
|
|
78
|
+
};
|
|
79
|
+
// Evaluate against each rule
|
|
80
|
+
for (const rule of this.config.rules) {
|
|
81
|
+
if (rule.enabled === false)
|
|
82
|
+
continue;
|
|
83
|
+
if (this.evaluateCondition(rule.condition, metadata)) {
|
|
84
|
+
matchedRules.push(rule.name);
|
|
85
|
+
const decision = this.createDecision(metadata, rule.action.moveTo, rule.name, accessPattern);
|
|
86
|
+
// Use the first matching high-confidence rule
|
|
87
|
+
if (decision.confidence >= (this.config.minConfidence ?? 0.7)) {
|
|
88
|
+
bestDecision = decision;
|
|
89
|
+
bestDecision.matchedRules = matchedRules;
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// Apply policy-specific logic if no rules matched
|
|
95
|
+
if (matchedRules.length === 0) {
|
|
96
|
+
bestDecision = await this.evaluateByPolicy(metadata, accessPattern);
|
|
97
|
+
}
|
|
98
|
+
return bestDecision;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Run a complete tiering cycle across all objects
|
|
102
|
+
*
|
|
103
|
+
* @param metadataList - List of all object metadata to evaluate
|
|
104
|
+
* @param onProgress - Optional progress callback
|
|
105
|
+
* @returns Cycle result with statistics
|
|
106
|
+
*/
|
|
107
|
+
async runTieringCycle(metadataList, onProgress) {
|
|
108
|
+
if (this.cycleInProgress) {
|
|
109
|
+
throw new Error('Tiering cycle already in progress');
|
|
110
|
+
}
|
|
111
|
+
this.cycleInProgress = true;
|
|
112
|
+
const startTime = new Date();
|
|
113
|
+
const result = {
|
|
114
|
+
startTime,
|
|
115
|
+
endTime: new Date(),
|
|
116
|
+
durationMs: 0,
|
|
117
|
+
objectsEvaluated: 0,
|
|
118
|
+
objectsPromoted: 0,
|
|
119
|
+
objectsDemoted: 0,
|
|
120
|
+
estimatedMonthlySavings: 0,
|
|
121
|
+
errors: [],
|
|
122
|
+
statistics: {
|
|
123
|
+
tierDistributionBefore: this.getTierDistribution(metadataList),
|
|
124
|
+
tierDistributionAfter: {},
|
|
125
|
+
dataMoved: 0,
|
|
126
|
+
avgConfidence: 0,
|
|
127
|
+
rulesApplied: {}
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
try {
|
|
131
|
+
// Limit objects per cycle
|
|
132
|
+
const objectsToProcess = metadataList.slice(0, this.config.maxObjectsPerCycle);
|
|
133
|
+
let totalConfidence = 0;
|
|
134
|
+
const decisions = [];
|
|
135
|
+
// Evaluate all objects
|
|
136
|
+
for (let i = 0; i < objectsToProcess.length; i++) {
|
|
137
|
+
const metadata = objectsToProcess[i];
|
|
138
|
+
try {
|
|
139
|
+
const decision = await this.evaluateObject(metadata.identifier, metadata);
|
|
140
|
+
decisions.push({ metadata, decision });
|
|
141
|
+
totalConfidence += decision.confidence;
|
|
142
|
+
result.objectsEvaluated++;
|
|
143
|
+
// Track rule usage
|
|
144
|
+
for (const ruleName of decision.matchedRules) {
|
|
145
|
+
result.statistics.rulesApplied[ruleName] =
|
|
146
|
+
(result.statistics.rulesApplied[ruleName] || 0) + 1;
|
|
147
|
+
}
|
|
148
|
+
if (onProgress) {
|
|
149
|
+
onProgress(i + 1, objectsToProcess.length);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
catch (error) {
|
|
153
|
+
result.errors.push({
|
|
154
|
+
identifier: metadata.identifier,
|
|
155
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
156
|
+
timestamp: new Date(),
|
|
157
|
+
operation: 'evaluate'
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
// Calculate statistics
|
|
162
|
+
if (result.objectsEvaluated > 0) {
|
|
163
|
+
result.statistics.avgConfidence = totalConfidence / result.objectsEvaluated;
|
|
164
|
+
}
|
|
165
|
+
// Execute tier changes (if not dry-run)
|
|
166
|
+
if (!this.config.dryRun) {
|
|
167
|
+
for (const { metadata, decision } of decisions) {
|
|
168
|
+
if (decision.shouldChange) {
|
|
169
|
+
try {
|
|
170
|
+
// This would be implemented by the caller
|
|
171
|
+
// We just track the intent here
|
|
172
|
+
if (this.isPromotion(decision.currentTier, decision.targetTier)) {
|
|
173
|
+
result.objectsPromoted++;
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
result.objectsDemoted++;
|
|
177
|
+
}
|
|
178
|
+
result.estimatedMonthlySavings += decision.costImpact;
|
|
179
|
+
result.statistics.dataMoved += metadata.size;
|
|
180
|
+
// Update metadata tier (would be done by caller)
|
|
181
|
+
metadata.tier = decision.targetTier;
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
result.errors.push({
|
|
185
|
+
identifier: metadata.identifier,
|
|
186
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
187
|
+
timestamp: new Date(),
|
|
188
|
+
operation: this.isPromotion(decision.currentTier, decision.targetTier)
|
|
189
|
+
? 'promote'
|
|
190
|
+
: 'demote'
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
// Calculate final tier distribution
|
|
197
|
+
result.statistics.tierDistributionAfter = this.getTierDistribution(objectsToProcess);
|
|
198
|
+
result.endTime = new Date();
|
|
199
|
+
result.durationMs = result.endTime.getTime() - startTime.getTime();
|
|
200
|
+
this.lastCycleTime = result.endTime;
|
|
201
|
+
return result;
|
|
202
|
+
}
|
|
203
|
+
finally {
|
|
204
|
+
this.cycleInProgress = false;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Get current configuration
|
|
209
|
+
*/
|
|
210
|
+
getConfig() {
|
|
211
|
+
return { ...this.config };
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Update configuration
|
|
215
|
+
*/
|
|
216
|
+
updateConfig(updates) {
|
|
217
|
+
this.config = { ...this.config, ...updates };
|
|
218
|
+
// Re-sort rules if updated
|
|
219
|
+
if (updates.rules) {
|
|
220
|
+
this.config.rules.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Get last cycle time
|
|
225
|
+
*/
|
|
226
|
+
getLastCycleTime() {
|
|
227
|
+
return this.lastCycleTime;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Check if cycle is in progress
|
|
231
|
+
*/
|
|
232
|
+
isCycleInProgress() {
|
|
233
|
+
return this.cycleInProgress;
|
|
234
|
+
}
|
|
235
|
+
// ========================================================================
|
|
236
|
+
// Private helper methods
|
|
237
|
+
// ========================================================================
|
|
238
|
+
/**
|
|
239
|
+
* Evaluate a tiering condition
|
|
240
|
+
*/
|
|
241
|
+
evaluateCondition(condition, metadata) {
|
|
242
|
+
let actualValue;
|
|
243
|
+
switch (condition.type) {
|
|
244
|
+
case 'age':
|
|
245
|
+
const ageMs = Date.now() - metadata.createdAt.getTime();
|
|
246
|
+
actualValue = ageMs / (24 * 60 * 60 * 1000); // Convert to days
|
|
247
|
+
break;
|
|
248
|
+
case 'last_accessed':
|
|
249
|
+
const lastAccessMs = Date.now() - metadata.lastAccessed.getTime();
|
|
250
|
+
actualValue = lastAccessMs / (24 * 60 * 60 * 1000); // Convert to days
|
|
251
|
+
break;
|
|
252
|
+
case 'access_count':
|
|
253
|
+
actualValue = metadata.accessCount;
|
|
254
|
+
break;
|
|
255
|
+
case 'size':
|
|
256
|
+
actualValue = metadata.size / (1024 * 1024); // Convert to MB
|
|
257
|
+
if (condition.unit === 'gb') {
|
|
258
|
+
actualValue = actualValue / 1024;
|
|
259
|
+
}
|
|
260
|
+
break;
|
|
261
|
+
case 'cost':
|
|
262
|
+
const currentCost = this.calculateMonthlyCost(metadata.tier, metadata.size);
|
|
263
|
+
actualValue = currentCost;
|
|
264
|
+
break;
|
|
265
|
+
default:
|
|
266
|
+
return false;
|
|
267
|
+
}
|
|
268
|
+
return this.compareValues(actualValue, condition.operator, condition.value);
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Compare values based on operator
|
|
272
|
+
*/
|
|
273
|
+
compareValues(actual, operator, expected) {
|
|
274
|
+
switch (operator) {
|
|
275
|
+
case 'gt': return actual > expected;
|
|
276
|
+
case 'gte': return actual >= expected;
|
|
277
|
+
case 'lt': return actual < expected;
|
|
278
|
+
case 'lte': return actual <= expected;
|
|
279
|
+
case 'eq': return actual === expected;
|
|
280
|
+
case 'ne': return actual !== expected;
|
|
281
|
+
default: return false;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Create a tiering decision
|
|
286
|
+
*/
|
|
287
|
+
createDecision(metadata, targetTier, reason, accessPattern) {
|
|
288
|
+
const currentCost = this.calculateMonthlyCost(metadata.tier, metadata.size);
|
|
289
|
+
const targetCost = this.calculateMonthlyCost(targetTier, metadata.size);
|
|
290
|
+
const costImpact = currentCost - targetCost;
|
|
291
|
+
// Calculate confidence based on access pattern
|
|
292
|
+
let confidence = 0.8; // Base confidence
|
|
293
|
+
if (accessPattern) {
|
|
294
|
+
confidence = accessPattern.recommendationConfidence;
|
|
295
|
+
}
|
|
296
|
+
return {
|
|
297
|
+
shouldChange: metadata.tier !== targetTier,
|
|
298
|
+
currentTier: metadata.tier,
|
|
299
|
+
targetTier,
|
|
300
|
+
reason,
|
|
301
|
+
costImpact,
|
|
302
|
+
confidence,
|
|
303
|
+
matchedRules: [reason]
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Evaluate by policy when no rules match
|
|
308
|
+
*/
|
|
309
|
+
async evaluateByPolicy(metadata, accessPattern) {
|
|
310
|
+
switch (this.config.policy) {
|
|
311
|
+
case TieringPolicy.COST_OPTIMIZED:
|
|
312
|
+
return this.evaluateCostOptimized(metadata, accessPattern);
|
|
313
|
+
case TieringPolicy.ACCESS_BASED:
|
|
314
|
+
return this.evaluateAccessBased(metadata, accessPattern);
|
|
315
|
+
case TieringPolicy.TIME_BASED:
|
|
316
|
+
return this.evaluateTimeBased(metadata);
|
|
317
|
+
case TieringPolicy.SIZE_BASED:
|
|
318
|
+
return this.evaluateSizeBased(metadata);
|
|
319
|
+
default:
|
|
320
|
+
return this.createDecision(metadata, metadata.tier, 'Default policy: no change', accessPattern);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Cost-optimized tier evaluation
|
|
325
|
+
*/
|
|
326
|
+
evaluateCostOptimized(metadata, accessPattern) {
|
|
327
|
+
if (accessPattern?.recommendedTier) {
|
|
328
|
+
return this.createDecision(metadata, accessPattern.recommendedTier, 'Cost optimization recommendation', accessPattern);
|
|
329
|
+
}
|
|
330
|
+
// Fallback: demote old, rarely accessed objects
|
|
331
|
+
const daysSinceAccess = (Date.now() - metadata.lastAccessed.getTime()) / (24 * 60 * 60 * 1000);
|
|
332
|
+
if (daysSinceAccess > 90 && metadata.tier !== StorageTier.GLACIER) {
|
|
333
|
+
return this.createDecision(metadata, StorageTier.GLACIER, 'Cost optimization: archive old object');
|
|
334
|
+
}
|
|
335
|
+
else if (daysSinceAccess > 30 && metadata.tier === StorageTier.HOT) {
|
|
336
|
+
return this.createDecision(metadata, StorageTier.COLD, 'Cost optimization: demote inactive object');
|
|
337
|
+
}
|
|
338
|
+
return this.createDecision(metadata, metadata.tier, 'Cost optimization: no change');
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Access-based tier evaluation
|
|
342
|
+
*/
|
|
343
|
+
evaluateAccessBased(metadata, accessPattern) {
|
|
344
|
+
const daysSinceAccess = (Date.now() - metadata.lastAccessed.getTime()) / (24 * 60 * 60 * 1000);
|
|
345
|
+
const accessFrequency = metadata.accessCount / Math.max(1, daysSinceAccess);
|
|
346
|
+
// High access frequency -> promote to HOT
|
|
347
|
+
if (accessFrequency > 1 && metadata.tier !== StorageTier.HOT) {
|
|
348
|
+
return this.createDecision(metadata, StorageTier.HOT, 'Frequent access detected', accessPattern);
|
|
349
|
+
}
|
|
350
|
+
// Low access frequency -> demote to COLD
|
|
351
|
+
if (accessFrequency < 0.1 && metadata.tier === StorageTier.HOT) {
|
|
352
|
+
return this.createDecision(metadata, StorageTier.COLD, 'Infrequent access detected', accessPattern);
|
|
353
|
+
}
|
|
354
|
+
return this.createDecision(metadata, metadata.tier, 'Access pattern: no change', accessPattern);
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Time-based tier evaluation
|
|
358
|
+
*/
|
|
359
|
+
evaluateTimeBased(metadata) {
|
|
360
|
+
const ageInDays = (Date.now() - metadata.createdAt.getTime()) / (24 * 60 * 60 * 1000);
|
|
361
|
+
if (ageInDays > 365 && metadata.tier !== StorageTier.GLACIER) {
|
|
362
|
+
return this.createDecision(metadata, StorageTier.GLACIER, 'Age-based: move to archive');
|
|
363
|
+
}
|
|
364
|
+
else if (ageInDays > 90 && metadata.tier === StorageTier.HOT) {
|
|
365
|
+
return this.createDecision(metadata, StorageTier.COLD, 'Age-based: demote old object');
|
|
366
|
+
}
|
|
367
|
+
return this.createDecision(metadata, metadata.tier, 'Age-based: no change');
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Size-based tier evaluation
|
|
371
|
+
*/
|
|
372
|
+
evaluateSizeBased(metadata) {
|
|
373
|
+
const sizeMB = metadata.size / (1024 * 1024);
|
|
374
|
+
// Small files stay in HOT for performance
|
|
375
|
+
if (sizeMB < 1 && metadata.tier !== StorageTier.HOT) {
|
|
376
|
+
return this.createDecision(metadata, StorageTier.HOT, 'Size-based: small file to hot tier');
|
|
377
|
+
}
|
|
378
|
+
// Large files go to COLD for cost savings
|
|
379
|
+
if (sizeMB > 100 && metadata.tier === StorageTier.HOT) {
|
|
380
|
+
return this.createDecision(metadata, StorageTier.COLD, 'Size-based: large file to cold tier');
|
|
381
|
+
}
|
|
382
|
+
return this.createDecision(metadata, metadata.tier, 'Size-based: no change');
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Calculate monthly cost for tier and size
|
|
386
|
+
*/
|
|
387
|
+
calculateMonthlyCost(tier, sizeBytes) {
|
|
388
|
+
const sizeGB = sizeBytes / (1024 * 1024 * 1024);
|
|
389
|
+
const costPerGB = this.config.tierCosts[tier] || 0;
|
|
390
|
+
return sizeGB * costPerGB;
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Check if tier change is a promotion (to hotter tier)
|
|
394
|
+
*/
|
|
395
|
+
isPromotion(from, to) {
|
|
396
|
+
const tierOrder = [
|
|
397
|
+
StorageTier.GLACIER,
|
|
398
|
+
StorageTier.COLD,
|
|
399
|
+
StorageTier.WARM,
|
|
400
|
+
StorageTier.HOT
|
|
401
|
+
];
|
|
402
|
+
return tierOrder.indexOf(to) > tierOrder.indexOf(from);
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Get tier distribution from metadata list
|
|
406
|
+
*/
|
|
407
|
+
getTierDistribution(metadataList) {
|
|
408
|
+
const distribution = {
|
|
409
|
+
[StorageTier.HOT]: 0,
|
|
410
|
+
[StorageTier.WARM]: 0,
|
|
411
|
+
[StorageTier.COLD]: 0,
|
|
412
|
+
[StorageTier.GLACIER]: 0
|
|
413
|
+
};
|
|
414
|
+
for (const metadata of metadataList) {
|
|
415
|
+
distribution[metadata.tier] = (distribution[metadata.tier] || 0) + 1;
|
|
416
|
+
}
|
|
417
|
+
return distribution;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"example.d.ts","sourceRoot":"","sources":["../../../../src/modules/storage/tiering/example.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAcH,iBAAe,IAAI,kBAoRlB;AAOD,OAAO,EAAE,IAAI,EAAE,CAAA"}
|