@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,227 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Varity SDK - Access Analyzer
|
|
3
|
+
*
|
|
4
|
+
* Tracks and analyzes access patterns for storage objects to enable
|
|
5
|
+
* intelligent tiering decisions. Provides predictive analytics and
|
|
6
|
+
* access frequency monitoring.
|
|
7
|
+
*
|
|
8
|
+
* Features:
|
|
9
|
+
* - Real-time access tracking
|
|
10
|
+
* - Pattern prediction
|
|
11
|
+
* - Access frequency analysis
|
|
12
|
+
* - Time-series analytics
|
|
13
|
+
* - Hot spot detection
|
|
14
|
+
*
|
|
15
|
+
* @packageDocumentation
|
|
16
|
+
*/
|
|
17
|
+
import { StorageTier, type AccessPattern } from '@varity-labs/types';
|
|
18
|
+
/**
|
|
19
|
+
* Access record for a single access event
|
|
20
|
+
*/
|
|
21
|
+
export interface AccessRecord {
|
|
22
|
+
/** Object identifier */
|
|
23
|
+
identifier: string;
|
|
24
|
+
/** Access timestamp */
|
|
25
|
+
timestamp: Date;
|
|
26
|
+
/** Access type */
|
|
27
|
+
type: 'read' | 'write' | 'delete' | 'list';
|
|
28
|
+
/** Bytes transferred */
|
|
29
|
+
bytesTransferred: number;
|
|
30
|
+
/** Request duration in milliseconds */
|
|
31
|
+
durationMs: number;
|
|
32
|
+
/** Source of access (IP, user ID, etc.) */
|
|
33
|
+
source?: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Access statistics for an object
|
|
37
|
+
*/
|
|
38
|
+
export interface AccessStats {
|
|
39
|
+
/** Object identifier */
|
|
40
|
+
identifier: string;
|
|
41
|
+
/** Total access count */
|
|
42
|
+
totalAccesses: number;
|
|
43
|
+
/** Read count */
|
|
44
|
+
readCount: number;
|
|
45
|
+
/** Write count */
|
|
46
|
+
writeCount: number;
|
|
47
|
+
/** First access timestamp */
|
|
48
|
+
firstAccess: Date;
|
|
49
|
+
/** Last access timestamp */
|
|
50
|
+
lastAccess: Date;
|
|
51
|
+
/** Average interval between accesses (seconds) */
|
|
52
|
+
avgAccessInterval: number;
|
|
53
|
+
/** Total bandwidth consumed (bytes) */
|
|
54
|
+
totalBandwidth: number;
|
|
55
|
+
/** Average request duration (milliseconds) */
|
|
56
|
+
avgDuration: number;
|
|
57
|
+
/** Access frequency trend */
|
|
58
|
+
trend: 'increasing' | 'decreasing' | 'stable';
|
|
59
|
+
/** Current storage tier */
|
|
60
|
+
currentTier?: StorageTier;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Time window for access analysis
|
|
64
|
+
*/
|
|
65
|
+
export interface TimeWindow {
|
|
66
|
+
/** Window start */
|
|
67
|
+
start: Date;
|
|
68
|
+
/** Window end */
|
|
69
|
+
end: Date;
|
|
70
|
+
/** Access count in window */
|
|
71
|
+
accessCount: number;
|
|
72
|
+
/** Bandwidth in window */
|
|
73
|
+
bandwidth: number;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Access pattern prediction
|
|
77
|
+
*/
|
|
78
|
+
export interface AccessPrediction {
|
|
79
|
+
/** Object identifier */
|
|
80
|
+
identifier: string;
|
|
81
|
+
/** Predicted access probability (0-1) for next time period */
|
|
82
|
+
probability: number;
|
|
83
|
+
/** Confidence in prediction (0-1) */
|
|
84
|
+
confidence: number;
|
|
85
|
+
/** Predicted access frequency (accesses per day) */
|
|
86
|
+
predictedFrequency: number;
|
|
87
|
+
/** Recommended tier based on prediction */
|
|
88
|
+
recommendedTier: StorageTier;
|
|
89
|
+
/** Time period for prediction (days) */
|
|
90
|
+
predictionPeriodDays: number;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Analyzer configuration
|
|
94
|
+
*/
|
|
95
|
+
export interface AccessAnalyzerConfig {
|
|
96
|
+
/** Maximum access records to keep in memory per object */
|
|
97
|
+
maxRecordsPerObject?: number;
|
|
98
|
+
/** Time window for recent access analysis (hours) */
|
|
99
|
+
recentAccessWindow?: number;
|
|
100
|
+
/** Enable predictive analytics */
|
|
101
|
+
enablePrediction?: boolean;
|
|
102
|
+
/** Minimum access count before making predictions */
|
|
103
|
+
minAccessesForPrediction?: number;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Advanced access pattern analyzer for intelligent tiering
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```typescript
|
|
110
|
+
* const analyzer = new AccessAnalyzer({
|
|
111
|
+
* maxRecordsPerObject: 1000,
|
|
112
|
+
* recentAccessWindow: 24,
|
|
113
|
+
* enablePrediction: true
|
|
114
|
+
* })
|
|
115
|
+
*
|
|
116
|
+
* // Record an access
|
|
117
|
+
* analyzer.recordAccess({
|
|
118
|
+
* identifier: 'obj-123',
|
|
119
|
+
* timestamp: new Date(),
|
|
120
|
+
* type: 'read',
|
|
121
|
+
* bytesTransferred: 1024 * 1024
|
|
122
|
+
* })
|
|
123
|
+
*
|
|
124
|
+
* // Get statistics
|
|
125
|
+
* const stats = analyzer.getAccessStats('obj-123')
|
|
126
|
+
* console.log(`Access count: ${stats.totalAccesses}`)
|
|
127
|
+
*
|
|
128
|
+
* // Predict future access
|
|
129
|
+
* const prediction = analyzer.predictAccessProbability('obj-123')
|
|
130
|
+
* console.log(`Predicted probability: ${prediction.probability}`)
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
133
|
+
export declare class AccessAnalyzer {
|
|
134
|
+
private config;
|
|
135
|
+
private accessRecords;
|
|
136
|
+
private statsCache;
|
|
137
|
+
private cacheTTL;
|
|
138
|
+
constructor(config?: AccessAnalyzerConfig);
|
|
139
|
+
/**
|
|
140
|
+
* Record an access event
|
|
141
|
+
*
|
|
142
|
+
* @param record - Access record to track
|
|
143
|
+
*/
|
|
144
|
+
recordAccess(record: AccessRecord): void;
|
|
145
|
+
/**
|
|
146
|
+
* Get access statistics for an object
|
|
147
|
+
*
|
|
148
|
+
* @param identifier - Object identifier
|
|
149
|
+
* @returns Access statistics
|
|
150
|
+
*/
|
|
151
|
+
getAccessStats(identifier: string): AccessStats;
|
|
152
|
+
/**
|
|
153
|
+
* Predict access probability for an object
|
|
154
|
+
*
|
|
155
|
+
* @param identifier - Object identifier
|
|
156
|
+
* @param periodDays - Prediction period in days
|
|
157
|
+
* @returns Access prediction
|
|
158
|
+
*/
|
|
159
|
+
predictAccessProbability(identifier: string, periodDays?: number): AccessPrediction;
|
|
160
|
+
/**
|
|
161
|
+
* Get access pattern for tiering decisions
|
|
162
|
+
*
|
|
163
|
+
* @param identifier - Object identifier
|
|
164
|
+
* @param currentTier - Current storage tier
|
|
165
|
+
* @param size - Object size in bytes
|
|
166
|
+
* @param tierCosts - Cost per GB per month for each tier
|
|
167
|
+
* @returns Access pattern with recommendations
|
|
168
|
+
*/
|
|
169
|
+
getAccessPattern(identifier: string, currentTier: StorageTier, size: number, tierCosts: Record<StorageTier, number>): AccessPattern;
|
|
170
|
+
/**
|
|
171
|
+
* Get hot spot objects (frequently accessed)
|
|
172
|
+
*
|
|
173
|
+
* @param topN - Number of hot spots to return
|
|
174
|
+
* @param timeWindowHours - Time window for analysis
|
|
175
|
+
* @returns List of hot spot identifiers with stats
|
|
176
|
+
*/
|
|
177
|
+
getHotSpots(topN?: number, timeWindowHours?: number): Array<{
|
|
178
|
+
identifier: string;
|
|
179
|
+
stats: AccessStats;
|
|
180
|
+
}>;
|
|
181
|
+
/**
|
|
182
|
+
* Get cold objects (rarely accessed)
|
|
183
|
+
*
|
|
184
|
+
* @param topN - Number of cold objects to return
|
|
185
|
+
* @param minAgeHours - Minimum age in hours
|
|
186
|
+
* @returns List of cold object identifiers with stats
|
|
187
|
+
*/
|
|
188
|
+
getColdObjects(topN?: number, minAgeHours?: number): Array<{
|
|
189
|
+
identifier: string;
|
|
190
|
+
stats: AccessStats;
|
|
191
|
+
}>;
|
|
192
|
+
/**
|
|
193
|
+
* Clear access records for an object
|
|
194
|
+
*
|
|
195
|
+
* @param identifier - Object identifier
|
|
196
|
+
*/
|
|
197
|
+
clearAccessRecords(identifier: string): void;
|
|
198
|
+
/**
|
|
199
|
+
* Clear all access records
|
|
200
|
+
*/
|
|
201
|
+
clearAllRecords(): void;
|
|
202
|
+
/**
|
|
203
|
+
* Export access records to JSON
|
|
204
|
+
*
|
|
205
|
+
* @returns Serialized access records
|
|
206
|
+
*/
|
|
207
|
+
exportRecords(): string;
|
|
208
|
+
/**
|
|
209
|
+
* Import access records from JSON
|
|
210
|
+
*
|
|
211
|
+
* @param json - Serialized access records
|
|
212
|
+
*/
|
|
213
|
+
importRecords(json: string): void;
|
|
214
|
+
/**
|
|
215
|
+
* Calculate average interval between accesses
|
|
216
|
+
*/
|
|
217
|
+
private calculateAvgInterval;
|
|
218
|
+
/**
|
|
219
|
+
* Detect access trend
|
|
220
|
+
*/
|
|
221
|
+
private detectTrend;
|
|
222
|
+
/**
|
|
223
|
+
* Recommend tier based on access frequency
|
|
224
|
+
*/
|
|
225
|
+
private recommendTierFromFrequency;
|
|
226
|
+
}
|
|
227
|
+
//# sourceMappingURL=AccessAnalyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AccessAnalyzer.d.ts","sourceRoot":"","sources":["../../../../src/modules/storage/tiering/AccessAnalyzer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Varity SDK - Access Analyzer
|
|
3
|
+
*
|
|
4
|
+
* Tracks and analyzes access patterns for storage objects to enable
|
|
5
|
+
* intelligent tiering decisions. Provides predictive analytics and
|
|
6
|
+
* access frequency monitoring.
|
|
7
|
+
*
|
|
8
|
+
* Features:
|
|
9
|
+
* - Real-time access tracking
|
|
10
|
+
* - Pattern prediction
|
|
11
|
+
* - Access frequency analysis
|
|
12
|
+
* - Time-series analytics
|
|
13
|
+
* - Hot spot detection
|
|
14
|
+
*
|
|
15
|
+
* @packageDocumentation
|
|
16
|
+
*/
|
|
17
|
+
import { StorageTier } from '@varity-labs/types';
|
|
18
|
+
/**
|
|
19
|
+
* Advanced access pattern analyzer for intelligent tiering
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* const analyzer = new AccessAnalyzer({
|
|
24
|
+
* maxRecordsPerObject: 1000,
|
|
25
|
+
* recentAccessWindow: 24,
|
|
26
|
+
* enablePrediction: true
|
|
27
|
+
* })
|
|
28
|
+
*
|
|
29
|
+
* // Record an access
|
|
30
|
+
* analyzer.recordAccess({
|
|
31
|
+
* identifier: 'obj-123',
|
|
32
|
+
* timestamp: new Date(),
|
|
33
|
+
* type: 'read',
|
|
34
|
+
* bytesTransferred: 1024 * 1024
|
|
35
|
+
* })
|
|
36
|
+
*
|
|
37
|
+
* // Get statistics
|
|
38
|
+
* const stats = analyzer.getAccessStats('obj-123')
|
|
39
|
+
* console.log(`Access count: ${stats.totalAccesses}`)
|
|
40
|
+
*
|
|
41
|
+
* // Predict future access
|
|
42
|
+
* const prediction = analyzer.predictAccessProbability('obj-123')
|
|
43
|
+
* console.log(`Predicted probability: ${prediction.probability}`)
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export class AccessAnalyzer {
|
|
47
|
+
constructor(config = {}) {
|
|
48
|
+
this.cacheTTL = 5 * 60 * 1000; // 5 minutes
|
|
49
|
+
this.config = {
|
|
50
|
+
maxRecordsPerObject: config.maxRecordsPerObject ?? 1000,
|
|
51
|
+
recentAccessWindow: config.recentAccessWindow ?? 24,
|
|
52
|
+
enablePrediction: config.enablePrediction ?? true,
|
|
53
|
+
minAccessesForPrediction: config.minAccessesForPrediction ?? 5
|
|
54
|
+
};
|
|
55
|
+
this.accessRecords = new Map();
|
|
56
|
+
this.statsCache = new Map();
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Record an access event
|
|
60
|
+
*
|
|
61
|
+
* @param record - Access record to track
|
|
62
|
+
*/
|
|
63
|
+
recordAccess(record) {
|
|
64
|
+
const { identifier } = record;
|
|
65
|
+
// Get or create records array
|
|
66
|
+
let records = this.accessRecords.get(identifier);
|
|
67
|
+
if (!records) {
|
|
68
|
+
records = [];
|
|
69
|
+
this.accessRecords.set(identifier, records);
|
|
70
|
+
}
|
|
71
|
+
// Add new record
|
|
72
|
+
records.push(record);
|
|
73
|
+
// Trim old records if exceeding limit
|
|
74
|
+
if (records.length > this.config.maxRecordsPerObject) {
|
|
75
|
+
records.shift(); // Remove oldest
|
|
76
|
+
}
|
|
77
|
+
// Invalidate stats cache
|
|
78
|
+
this.statsCache.delete(identifier);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Get access statistics for an object
|
|
82
|
+
*
|
|
83
|
+
* @param identifier - Object identifier
|
|
84
|
+
* @returns Access statistics
|
|
85
|
+
*/
|
|
86
|
+
getAccessStats(identifier) {
|
|
87
|
+
// Check cache
|
|
88
|
+
const cached = this.statsCache.get(identifier);
|
|
89
|
+
if (cached && Date.now() - cached.timestamp < this.cacheTTL) {
|
|
90
|
+
return cached.stats;
|
|
91
|
+
}
|
|
92
|
+
const records = this.accessRecords.get(identifier) || [];
|
|
93
|
+
if (records.length === 0) {
|
|
94
|
+
// No access history
|
|
95
|
+
const stats = {
|
|
96
|
+
identifier,
|
|
97
|
+
totalAccesses: 0,
|
|
98
|
+
readCount: 0,
|
|
99
|
+
writeCount: 0,
|
|
100
|
+
firstAccess: new Date(),
|
|
101
|
+
lastAccess: new Date(),
|
|
102
|
+
avgAccessInterval: 0,
|
|
103
|
+
totalBandwidth: 0,
|
|
104
|
+
avgDuration: 0,
|
|
105
|
+
trend: 'stable'
|
|
106
|
+
};
|
|
107
|
+
return stats;
|
|
108
|
+
}
|
|
109
|
+
// Calculate statistics
|
|
110
|
+
const stats = {
|
|
111
|
+
identifier,
|
|
112
|
+
totalAccesses: records.length,
|
|
113
|
+
readCount: records.filter(r => r.type === 'read').length,
|
|
114
|
+
writeCount: records.filter(r => r.type === 'write').length,
|
|
115
|
+
firstAccess: records[0].timestamp,
|
|
116
|
+
lastAccess: records[records.length - 1].timestamp,
|
|
117
|
+
avgAccessInterval: this.calculateAvgInterval(records),
|
|
118
|
+
totalBandwidth: records.reduce((sum, r) => sum + r.bytesTransferred, 0),
|
|
119
|
+
avgDuration: records.reduce((sum, r) => sum + r.durationMs, 0) / records.length,
|
|
120
|
+
trend: this.detectTrend(records)
|
|
121
|
+
};
|
|
122
|
+
// Cache the result
|
|
123
|
+
this.statsCache.set(identifier, {
|
|
124
|
+
stats,
|
|
125
|
+
timestamp: Date.now()
|
|
126
|
+
});
|
|
127
|
+
return stats;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Predict access probability for an object
|
|
131
|
+
*
|
|
132
|
+
* @param identifier - Object identifier
|
|
133
|
+
* @param periodDays - Prediction period in days
|
|
134
|
+
* @returns Access prediction
|
|
135
|
+
*/
|
|
136
|
+
predictAccessProbability(identifier, periodDays = 7) {
|
|
137
|
+
const records = this.accessRecords.get(identifier) || [];
|
|
138
|
+
// Not enough data for prediction
|
|
139
|
+
if (records.length < this.config.minAccessesForPrediction) {
|
|
140
|
+
return {
|
|
141
|
+
identifier,
|
|
142
|
+
probability: 0.5,
|
|
143
|
+
confidence: 0.1,
|
|
144
|
+
predictedFrequency: 0,
|
|
145
|
+
recommendedTier: StorageTier.COLD,
|
|
146
|
+
predictionPeriodDays: periodDays
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
const stats = this.getAccessStats(identifier);
|
|
150
|
+
// Calculate access frequency (accesses per day)
|
|
151
|
+
const totalDays = (stats.lastAccess.getTime() - stats.firstAccess.getTime()) / (24 * 60 * 60 * 1000);
|
|
152
|
+
const accessesPerDay = totalDays > 0 ? stats.totalAccesses / totalDays : 0;
|
|
153
|
+
// Calculate recent access frequency (last N hours)
|
|
154
|
+
const recentWindow = this.config.recentAccessWindow * 60 * 60 * 1000;
|
|
155
|
+
const recentAccesses = records.filter(r => Date.now() - r.timestamp.getTime() < recentWindow).length;
|
|
156
|
+
const recentFrequency = recentAccesses / (this.config.recentAccessWindow / 24);
|
|
157
|
+
// Predict probability based on trend and frequency
|
|
158
|
+
let probability = 0.5;
|
|
159
|
+
let confidence = 0.5;
|
|
160
|
+
if (stats.trend === 'increasing') {
|
|
161
|
+
probability = Math.min(0.95, recentFrequency / (periodDays * 10));
|
|
162
|
+
confidence = 0.7;
|
|
163
|
+
}
|
|
164
|
+
else if (stats.trend === 'decreasing') {
|
|
165
|
+
probability = Math.max(0.05, accessesPerDay / (periodDays * 5));
|
|
166
|
+
confidence = 0.7;
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
// Stable trend
|
|
170
|
+
probability = Math.min(0.9, accessesPerDay / (periodDays * 2));
|
|
171
|
+
confidence = 0.8;
|
|
172
|
+
}
|
|
173
|
+
// Recommend tier based on predicted frequency
|
|
174
|
+
const recommendedTier = this.recommendTierFromFrequency(recentFrequency);
|
|
175
|
+
// Adjust confidence based on data quality
|
|
176
|
+
confidence = Math.min(confidence, stats.totalAccesses / this.config.minAccessesForPrediction);
|
|
177
|
+
return {
|
|
178
|
+
identifier,
|
|
179
|
+
probability,
|
|
180
|
+
confidence,
|
|
181
|
+
predictedFrequency: recentFrequency,
|
|
182
|
+
recommendedTier,
|
|
183
|
+
predictionPeriodDays: periodDays
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Get access pattern for tiering decisions
|
|
188
|
+
*
|
|
189
|
+
* @param identifier - Object identifier
|
|
190
|
+
* @param currentTier - Current storage tier
|
|
191
|
+
* @param size - Object size in bytes
|
|
192
|
+
* @param tierCosts - Cost per GB per month for each tier
|
|
193
|
+
* @returns Access pattern with recommendations
|
|
194
|
+
*/
|
|
195
|
+
getAccessPattern(identifier, currentTier, size, tierCosts) {
|
|
196
|
+
const stats = this.getAccessStats(identifier);
|
|
197
|
+
const prediction = this.predictAccessProbability(identifier);
|
|
198
|
+
// Calculate cost savings for recommended tier
|
|
199
|
+
const currentCostPerMonth = (size / (1024 * 1024 * 1024)) * tierCosts[currentTier];
|
|
200
|
+
const recommendedCostPerMonth = (size / (1024 * 1024 * 1024)) * tierCosts[prediction.recommendedTier];
|
|
201
|
+
const costSavingsEstimate = currentCostPerMonth - recommendedCostPerMonth;
|
|
202
|
+
return {
|
|
203
|
+
identifier,
|
|
204
|
+
accessCount: stats.totalAccesses,
|
|
205
|
+
lastAccessed: stats.lastAccess,
|
|
206
|
+
averageAccessInterval: stats.avgAccessInterval / (24 * 60 * 60), // Convert to days
|
|
207
|
+
totalBandwidth: stats.totalBandwidth,
|
|
208
|
+
currentTier,
|
|
209
|
+
recommendedTier: prediction.recommendedTier,
|
|
210
|
+
costSavingsEstimate,
|
|
211
|
+
recommendationConfidence: prediction.confidence
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Get hot spot objects (frequently accessed)
|
|
216
|
+
*
|
|
217
|
+
* @param topN - Number of hot spots to return
|
|
218
|
+
* @param timeWindowHours - Time window for analysis
|
|
219
|
+
* @returns List of hot spot identifiers with stats
|
|
220
|
+
*/
|
|
221
|
+
getHotSpots(topN = 10, timeWindowHours = 24) {
|
|
222
|
+
const windowMs = timeWindowHours * 60 * 60 * 1000;
|
|
223
|
+
const cutoffTime = Date.now() - windowMs;
|
|
224
|
+
const hotSpots = [];
|
|
225
|
+
for (const [identifier, records] of this.accessRecords.entries()) {
|
|
226
|
+
const recentAccesses = records.filter(r => r.timestamp.getTime() >= cutoffTime).length;
|
|
227
|
+
if (recentAccesses > 0) {
|
|
228
|
+
hotSpots.push({
|
|
229
|
+
identifier,
|
|
230
|
+
accessCount: recentAccesses,
|
|
231
|
+
stats: this.getAccessStats(identifier)
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
// Sort by access count and return top N
|
|
236
|
+
return hotSpots
|
|
237
|
+
.sort((a, b) => b.accessCount - a.accessCount)
|
|
238
|
+
.slice(0, topN)
|
|
239
|
+
.map(({ identifier, stats }) => ({ identifier, stats }));
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Get cold objects (rarely accessed)
|
|
243
|
+
*
|
|
244
|
+
* @param topN - Number of cold objects to return
|
|
245
|
+
* @param minAgeHours - Minimum age in hours
|
|
246
|
+
* @returns List of cold object identifiers with stats
|
|
247
|
+
*/
|
|
248
|
+
getColdObjects(topN = 10, minAgeHours = 168 // 7 days
|
|
249
|
+
) {
|
|
250
|
+
const minAgeMs = minAgeHours * 60 * 60 * 1000;
|
|
251
|
+
const cutoffTime = Date.now() - minAgeMs;
|
|
252
|
+
const coldObjects = [];
|
|
253
|
+
for (const [identifier, records] of this.accessRecords.entries()) {
|
|
254
|
+
if (records.length === 0)
|
|
255
|
+
continue;
|
|
256
|
+
const lastAccess = records[records.length - 1].timestamp.getTime();
|
|
257
|
+
const daysSinceAccess = (Date.now() - lastAccess) / (24 * 60 * 60 * 1000);
|
|
258
|
+
if (lastAccess < cutoffTime) {
|
|
259
|
+
coldObjects.push({
|
|
260
|
+
identifier,
|
|
261
|
+
daysSinceAccess,
|
|
262
|
+
stats: this.getAccessStats(identifier)
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
// Sort by days since last access (descending) and return top N
|
|
267
|
+
return coldObjects
|
|
268
|
+
.sort((a, b) => b.daysSinceAccess - a.daysSinceAccess)
|
|
269
|
+
.slice(0, topN)
|
|
270
|
+
.map(({ identifier, stats }) => ({ identifier, stats }));
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Clear access records for an object
|
|
274
|
+
*
|
|
275
|
+
* @param identifier - Object identifier
|
|
276
|
+
*/
|
|
277
|
+
clearAccessRecords(identifier) {
|
|
278
|
+
this.accessRecords.delete(identifier);
|
|
279
|
+
this.statsCache.delete(identifier);
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Clear all access records
|
|
283
|
+
*/
|
|
284
|
+
clearAllRecords() {
|
|
285
|
+
this.accessRecords.clear();
|
|
286
|
+
this.statsCache.clear();
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Export access records to JSON
|
|
290
|
+
*
|
|
291
|
+
* @returns Serialized access records
|
|
292
|
+
*/
|
|
293
|
+
exportRecords() {
|
|
294
|
+
const data = {};
|
|
295
|
+
for (const [identifier, records] of this.accessRecords.entries()) {
|
|
296
|
+
data[identifier] = records;
|
|
297
|
+
}
|
|
298
|
+
return JSON.stringify(data, null, 2);
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Import access records from JSON
|
|
302
|
+
*
|
|
303
|
+
* @param json - Serialized access records
|
|
304
|
+
*/
|
|
305
|
+
importRecords(json) {
|
|
306
|
+
const data = JSON.parse(json);
|
|
307
|
+
this.accessRecords.clear();
|
|
308
|
+
this.statsCache.clear();
|
|
309
|
+
for (const [identifier, records] of Object.entries(data)) {
|
|
310
|
+
this.accessRecords.set(identifier, records.map(r => ({
|
|
311
|
+
...r,
|
|
312
|
+
timestamp: new Date(r.timestamp)
|
|
313
|
+
})));
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
// ========================================================================
|
|
317
|
+
// Private helper methods
|
|
318
|
+
// ========================================================================
|
|
319
|
+
/**
|
|
320
|
+
* Calculate average interval between accesses
|
|
321
|
+
*/
|
|
322
|
+
calculateAvgInterval(records) {
|
|
323
|
+
if (records.length < 2)
|
|
324
|
+
return 0;
|
|
325
|
+
const intervals = [];
|
|
326
|
+
for (let i = 1; i < records.length; i++) {
|
|
327
|
+
const interval = records[i].timestamp.getTime() - records[i - 1].timestamp.getTime();
|
|
328
|
+
intervals.push(interval / 1000); // Convert to seconds
|
|
329
|
+
}
|
|
330
|
+
return intervals.reduce((sum, val) => sum + val, 0) / intervals.length;
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Detect access trend
|
|
334
|
+
*/
|
|
335
|
+
detectTrend(records) {
|
|
336
|
+
if (records.length < 4)
|
|
337
|
+
return 'stable';
|
|
338
|
+
// Split into two halves and compare access frequency
|
|
339
|
+
const midpoint = Math.floor(records.length / 2);
|
|
340
|
+
const firstHalf = records.slice(0, midpoint);
|
|
341
|
+
const secondHalf = records.slice(midpoint);
|
|
342
|
+
const firstDuration = firstHalf[firstHalf.length - 1].timestamp.getTime() - firstHalf[0].timestamp.getTime();
|
|
343
|
+
const secondDuration = secondHalf[secondHalf.length - 1].timestamp.getTime() - secondHalf[0].timestamp.getTime();
|
|
344
|
+
if (firstDuration === 0 || secondDuration === 0)
|
|
345
|
+
return 'stable';
|
|
346
|
+
const firstFrequency = firstHalf.length / firstDuration;
|
|
347
|
+
const secondFrequency = secondHalf.length / secondDuration;
|
|
348
|
+
const ratio = secondFrequency / firstFrequency;
|
|
349
|
+
if (ratio > 1.2)
|
|
350
|
+
return 'increasing';
|
|
351
|
+
if (ratio < 0.8)
|
|
352
|
+
return 'decreasing';
|
|
353
|
+
return 'stable';
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Recommend tier based on access frequency
|
|
357
|
+
*/
|
|
358
|
+
recommendTierFromFrequency(accessesPerDay) {
|
|
359
|
+
if (accessesPerDay >= 10)
|
|
360
|
+
return StorageTier.HOT;
|
|
361
|
+
if (accessesPerDay >= 1)
|
|
362
|
+
return StorageTier.WARM;
|
|
363
|
+
if (accessesPerDay >= 0.1)
|
|
364
|
+
return StorageTier.COLD;
|
|
365
|
+
return StorageTier.GLACIER;
|
|
366
|
+
}
|
|
367
|
+
}
|