mirror of
https://github.com/luxfi/dex.git
synced 2026-09-24 00:26:31 +00:00
563 lines
20 KiB
Go
563 lines
20 KiB
Go
package main
|
||
|
||
import (
|
||
"fmt"
|
||
"runtime"
|
||
"runtime/debug"
|
||
)
|
||
|
||
// Complete feature set memory structures
|
||
|
||
// User account with all features
|
||
type UserAccount struct {
|
||
UserID uint64 // 8 bytes
|
||
Username string // ~32 bytes avg
|
||
Email string // ~32 bytes avg
|
||
KYCData [256]byte // 256 bytes
|
||
Positions map[string]*Position // Variable
|
||
Orders map[uint64]*Order // Variable
|
||
TradeHistory []Trade // Variable
|
||
Balances map[string]float64 // Variable per asset
|
||
MarginAccount *MarginAccount // Pointer
|
||
VaultPositions map[uint64]*VaultPosition // Variable
|
||
StakingPositions map[string]*StakePosition // Variable
|
||
APIKeys []APIKey // Variable
|
||
Sessions []Session // Variable
|
||
Notifications []Notification // Variable
|
||
Settings UserSettings // ~1KB
|
||
}
|
||
|
||
// Position tracking
|
||
type Position struct {
|
||
Symbol string // 16 bytes
|
||
Side uint8 // 1 byte
|
||
Size float64 // 8 bytes
|
||
EntryPrice float64 // 8 bytes
|
||
MarkPrice float64 // 8 bytes
|
||
UnrealizedPNL float64 // 8 bytes
|
||
RealizedPNL float64 // 8 bytes
|
||
Margin float64 // 8 bytes
|
||
Leverage uint8 // 1 byte
|
||
LiquidationPrice float64 // 8 bytes
|
||
UpdateTime int64 // 8 bytes
|
||
} // ~82 bytes
|
||
|
||
// Margin account
|
||
type MarginAccount struct {
|
||
AccountValue float64 // 8 bytes
|
||
BuyingPower float64 // 8 bytes
|
||
MaintenanceMargin float64 // 8 bytes
|
||
InitialMargin float64 // 8 bytes
|
||
MarginRatio float64 // 8 bytes
|
||
CrossMargin bool // 1 byte
|
||
IsolatedPositions map[string]float64 // Variable
|
||
CollateralAssets map[string]float64 // Variable
|
||
BorrowedAssets map[string]float64 // Variable
|
||
InterestRates map[string]float64 // Variable
|
||
MarginCalls []MarginCall // Variable
|
||
} // ~200+ bytes with maps
|
||
|
||
// Vault position
|
||
type VaultPosition struct {
|
||
VaultID uint64 // 8 bytes
|
||
DepositAmount float64 // 8 bytes
|
||
SharesOwned float64 // 8 bytes
|
||
CurrentValue float64 // 8 bytes
|
||
PendingRewards float64 // 8 bytes
|
||
LockupPeriod int64 // 8 bytes
|
||
APY float64 // 8 bytes
|
||
Strategy string // 32 bytes
|
||
} // ~88 bytes
|
||
|
||
// Staking position
|
||
type StakePosition struct {
|
||
StakeID uint64 // 8 bytes
|
||
Amount float64 // 8 bytes
|
||
RewardRate float64 // 8 bytes
|
||
AccruedRewards float64 // 8 bytes
|
||
StartTime int64 // 8 bytes
|
||
UnlockTime int64 // 8 bytes
|
||
Validator string // 32 bytes
|
||
} // ~80 bytes
|
||
|
||
// Settlement tracking
|
||
type Settlement struct {
|
||
SettlementID uint64 // 8 bytes
|
||
TradeID uint64 // 8 bytes
|
||
UserID uint64 // 8 bytes
|
||
CounterpartyID uint64 // 8 bytes
|
||
Amount float64 // 8 bytes
|
||
Asset string // 16 bytes
|
||
Status uint8 // 1 byte
|
||
SettlementTime int64 // 8 bytes
|
||
BlockNumber uint64 // 8 bytes
|
||
TxHash [32]byte // 32 bytes
|
||
Netting []NettingEntry // Variable
|
||
} // ~105+ bytes
|
||
|
||
type NettingEntry struct {
|
||
TradeID uint64 // 8 bytes
|
||
Amount float64 // 8 bytes
|
||
Fee float64 // 8 bytes
|
||
} // 24 bytes
|
||
|
||
// Order with all features
|
||
type Order struct {
|
||
OrderID uint64 // 8 bytes
|
||
UserID uint64 // 8 bytes
|
||
Symbol string // 16 bytes
|
||
Side uint8 // 1 byte
|
||
Type uint8 // 1 byte
|
||
Price float64 // 8 bytes
|
||
Size float64 // 8 bytes
|
||
FilledSize float64 // 8 bytes
|
||
RemainingSize float64 // 8 bytes
|
||
Status uint8 // 1 byte
|
||
TimeInForce uint8 // 1 byte
|
||
PostOnly bool // 1 byte
|
||
ReduceOnly bool // 1 byte
|
||
CloseOnTrigger bool // 1 byte
|
||
TriggerPrice float64 // 8 bytes
|
||
TrailingPercent float64 // 8 bytes
|
||
TakeProfitPrice float64 // 8 bytes
|
||
StopLossPrice float64 // 8 bytes
|
||
Commission float64 // 8 bytes
|
||
CreateTime int64 // 8 bytes
|
||
UpdateTime int64 // 8 bytes
|
||
} // ~113 bytes
|
||
|
||
// Trade record
|
||
type Trade struct {
|
||
TradeID uint64 // 8 bytes
|
||
OrderID uint64 // 8 bytes
|
||
Symbol string // 16 bytes
|
||
Side uint8 // 1 byte
|
||
Price float64 // 8 bytes
|
||
Size float64 // 8 bytes
|
||
Fee float64 // 8 bytes
|
||
FeeCurrency string // 8 bytes
|
||
IsMaker bool // 1 byte
|
||
ExecutionTime int64 // 8 bytes
|
||
} // ~74 bytes
|
||
|
||
// Risk management
|
||
type RiskProfile struct {
|
||
UserID uint64 // 8 bytes
|
||
RiskScore float64 // 8 bytes
|
||
MaxLeverage uint8 // 1 byte
|
||
MaxPositionSize float64 // 8 bytes
|
||
DailyLossLimit float64 // 8 bytes
|
||
MaxOpenPositions int // 8 bytes
|
||
RequiredMarginRatio float64 // 8 bytes
|
||
MaintenanceMargin float64 // 8 bytes
|
||
LiquidationHistory []LiquidationEvent // Variable
|
||
RiskFlags uint32 // 4 bytes
|
||
} // ~61+ bytes
|
||
|
||
type LiquidationEvent struct {
|
||
Timestamp int64 // 8 bytes
|
||
PositionSize float64 // 8 bytes
|
||
LossAmount float64 // 8 bytes
|
||
Symbol string // 16 bytes
|
||
} // 40 bytes
|
||
|
||
// Market data cache
|
||
type MarketDataCache struct {
|
||
Symbol string // 16 bytes
|
||
BidPrices [100]float64 // 800 bytes (L2 depth)
|
||
BidSizes [100]float64 // 800 bytes
|
||
AskPrices [100]float64 // 800 bytes
|
||
AskSizes [100]float64 // 800 bytes
|
||
LastPrice float64 // 8 bytes
|
||
Volume24h float64 // 8 bytes
|
||
High24h float64 // 8 bytes
|
||
Low24h float64 // 8 bytes
|
||
OpenInterest float64 // 8 bytes
|
||
FundingRate float64 // 8 bytes
|
||
MarkPrice float64 // 8 bytes
|
||
IndexPrice float64 // 8 bytes
|
||
OHLCVBars [1440]OHLCV // 1440 1-min bars = 46KB
|
||
Trades [1000]Trade // Recent trades = 74KB
|
||
UpdateTime int64 // 8 bytes
|
||
} // ~124 KB per market!
|
||
|
||
type OHLCV struct {
|
||
Time int64 // 8 bytes
|
||
Open float64 // 8 bytes
|
||
High float64 // 8 bytes
|
||
Low float64 // 8 bytes
|
||
Close float64 // 8 bytes
|
||
Volume float64 // 8 bytes
|
||
} // 48 bytes
|
||
|
||
// Session management
|
||
type Session struct {
|
||
SessionID string // 32 bytes
|
||
IP string // 16 bytes
|
||
UserAgent string // 128 bytes
|
||
LoginTime int64 // 8 bytes
|
||
LastActivity int64 // 8 bytes
|
||
ExpiryTime int64 // 8 bytes
|
||
} // ~200 bytes
|
||
|
||
type APIKey struct {
|
||
KeyID string // 32 bytes
|
||
Permissions []string // Variable
|
||
RateLimit int // 8 bytes
|
||
CreatedAt int64 // 8 bytes
|
||
} // ~48+ bytes
|
||
|
||
type Notification struct {
|
||
ID uint64 // 8 bytes
|
||
Type string // 16 bytes
|
||
Message string // 256 bytes avg
|
||
Timestamp int64 // 8 bytes
|
||
Read bool // 1 byte
|
||
} // ~289 bytes
|
||
|
||
type UserSettings struct {
|
||
Theme string // 16 bytes
|
||
Language string // 8 bytes
|
||
Timezone string // 32 bytes
|
||
EmailAlerts bool // 1 byte
|
||
PushAlerts bool // 1 byte
|
||
TradingSettings map[string]string // ~500 bytes
|
||
UIPreferences map[string]string // ~500 bytes
|
||
} // ~1KB
|
||
|
||
type MarginCall struct {
|
||
Timestamp int64 // 8 bytes
|
||
RequiredAmount float64 // 8 bytes
|
||
Deadline int64 // 8 bytes
|
||
Status uint8 // 1 byte
|
||
} // 25 bytes
|
||
|
||
func main() {
|
||
runtime.GC()
|
||
debug.FreeOSMemory()
|
||
|
||
fmt.Println("╔════════════════════════════════════════════════════════════════════════╗")
|
||
fmt.Println("║ COMPLETE LX DEX Memory Analysis - ALL Features for Millions ║")
|
||
fmt.Println("╚════════════════════════════════════════════════════════════════════════╝")
|
||
fmt.Println()
|
||
|
||
// Configuration
|
||
numMarkets := 21000 // 11K securities + 10K crypto
|
||
numUsers := 1_000_000 // 1 million active users
|
||
numVaults := 1000 // 1000 vault strategies
|
||
|
||
fmt.Println("System Configuration:")
|
||
fmt.Printf(" • Markets: %s (11K securities + 10K crypto)\n", formatNumber(numMarkets))
|
||
fmt.Printf(" • Active Users: %s\n", formatNumber(numUsers))
|
||
fmt.Printf(" • Vault Strategies: %s\n", formatNumber(numVaults))
|
||
fmt.Printf(" • Target Hardware: Mac Studio M2 Ultra (512GB)\n")
|
||
fmt.Println()
|
||
|
||
// Calculate memory requirements
|
||
fmt.Println("═══════════════════════════════════════════════════════════════════════")
|
||
fmt.Println("MEMORY BREAKDOWN BY COMPONENT")
|
||
fmt.Println("═══════════════════════════════════════════════════════════════════════")
|
||
fmt.Println()
|
||
|
||
var totalMemory int64
|
||
|
||
// 1. Order Books (from previous analysis)
|
||
orderBookMem := calculateOrderBookMemory(numMarkets)
|
||
totalMemory += orderBookMem
|
||
|
||
// 2. Market Data Cache
|
||
marketDataMem := calculateMarketDataMemory(numMarkets)
|
||
totalMemory += marketDataMem
|
||
|
||
// 3. User Accounts
|
||
userAccountMem := calculateUserMemory(numUsers)
|
||
totalMemory += userAccountMem
|
||
|
||
// 4. Active Positions
|
||
positionsMem := calculatePositionsMemory(numUsers)
|
||
totalMemory += positionsMem
|
||
|
||
// 5. Margin System
|
||
marginMem := calculateMarginMemory(numUsers)
|
||
totalMemory += marginMem
|
||
|
||
// 6. Vaults
|
||
vaultMem := calculateVaultMemory(numVaults, numUsers)
|
||
totalMemory += vaultMem
|
||
|
||
// 7. Settlement Engine
|
||
settlementMem := calculateSettlementMemory(numUsers)
|
||
totalMemory += settlementMem
|
||
|
||
// 8. Risk Management
|
||
riskMem := calculateRiskMemory(numUsers)
|
||
totalMemory += riskMem
|
||
|
||
// 9. Session Management
|
||
sessionMem := calculateSessionMemory(numUsers)
|
||
totalMemory += sessionMem
|
||
|
||
// 10. Trade History
|
||
tradeHistoryMem := calculateTradeHistoryMemory(numUsers)
|
||
totalMemory += tradeHistoryMem
|
||
|
||
// Summary
|
||
fmt.Println()
|
||
fmt.Println("═══════════════════════════════════════════════════════════════════════")
|
||
fmt.Println("TOTAL MEMORY REQUIREMENTS")
|
||
fmt.Println("═══════════════════════════════════════════════════════════════════════")
|
||
fmt.Printf("\nTotal Memory Required: %s\n", formatBytes(totalMemory))
|
||
fmt.Printf("Percentage of 512GB: %.2f%%\n", float64(totalMemory)*100/(512*1024*1024*1024))
|
||
|
||
// Mac Studio Analysis
|
||
fmt.Println()
|
||
fmt.Println("═══════════════════════════════════════════════════════════════════════")
|
||
fmt.Println("MAC STUDIO M2 ULTRA (512GB) ANALYSIS")
|
||
fmt.Println("═══════════════════════════════════════════════════════════════════════")
|
||
|
||
availableMemory := int64(462) * 1024 * 1024 * 1024 // 462GB available
|
||
|
||
fmt.Printf("\nAvailable Memory: 462 GB\n")
|
||
fmt.Printf("Required Memory: %.2f GB\n", float64(totalMemory)/(1024*1024*1024))
|
||
fmt.Printf("Remaining Memory: %.2f GB\n", float64(availableMemory-totalMemory)/(1024*1024*1024))
|
||
fmt.Printf("Utilization: %.2f%%\n", float64(totalMemory)*100/float64(availableMemory))
|
||
|
||
if totalMemory < availableMemory {
|
||
fmt.Println("\nStatus: ✅ SYSTEM CAN HANDLE FULL PRODUCTION LOAD")
|
||
|
||
// Calculate maximum scale
|
||
scaleFactor := float64(availableMemory) / float64(totalMemory)
|
||
fmt.Printf("\nMaximum Capacity:")
|
||
fmt.Printf("\n • Max Users: %s (%.1fx current)\n",
|
||
formatNumber(int(float64(numUsers)*scaleFactor)), scaleFactor)
|
||
fmt.Printf(" • Max Markets: %s (%.1fx current)\n",
|
||
formatNumber(int(float64(numMarkets)*scaleFactor)), scaleFactor)
|
||
} else {
|
||
fmt.Println("\nStatus: ❌ EXCEEDS AVAILABLE MEMORY")
|
||
fmt.Println("Recommendation: Use distributed architecture or reduce features")
|
||
}
|
||
|
||
// Per-user metrics
|
||
fmt.Println()
|
||
fmt.Println("═══════════════════════════════════════════════════════════════════════")
|
||
fmt.Println("PER-USER METRICS")
|
||
fmt.Println("═══════════════════════════════════════════════════════════════════════")
|
||
perUserMem := totalMemory / int64(numUsers)
|
||
fmt.Printf("\nMemory per user: %s\n", formatBytes(perUserMem))
|
||
fmt.Printf("Users per GB: %d\n", 1024*1024*1024/int(perUserMem))
|
||
|
||
// Optimization recommendations
|
||
fmt.Println()
|
||
fmt.Println("═══════════════════════════════════════════════════════════════════════")
|
||
fmt.Println("OPTIMIZATION STRATEGIES")
|
||
fmt.Println("═══════════════════════════════════════════════════════════════════════")
|
||
fmt.Println("\n1. Tiered Storage:")
|
||
fmt.Println(" • Hot: Active users (last 24h) in memory")
|
||
fmt.Println(" • Warm: Recent users (last 7d) in SSD cache")
|
||
fmt.Println(" • Cold: Inactive users in database")
|
||
|
||
fmt.Println("\n2. Data Compression:")
|
||
fmt.Println(" • OHLCV bars: Delta encoding (70% reduction)")
|
||
fmt.Println(" • Trade history: Compression (60% reduction)")
|
||
fmt.Println(" • Market data: Shared price levels (50% reduction)")
|
||
|
||
fmt.Println("\n3. Dynamic Loading:")
|
||
fmt.Println(" • Load user data on login")
|
||
fmt.Println(" • Evict inactive sessions after 1 hour")
|
||
fmt.Println(" • Stream market data on demand")
|
||
}
|
||
|
||
func calculateOrderBookMemory(numMarkets int) int64 {
|
||
// From optimized analysis: 4KB per market
|
||
perMarketMem := int64(4 * 1024)
|
||
total := perMarketMem * int64(numMarkets)
|
||
|
||
fmt.Println("1. ORDER BOOKS")
|
||
fmt.Printf(" Markets: %d\n", numMarkets)
|
||
fmt.Printf(" Memory per market: 4 KB\n")
|
||
fmt.Printf(" Total: %s\n", formatBytes(total))
|
||
|
||
return total
|
||
}
|
||
|
||
func calculateMarketDataMemory(numMarkets int) int64 {
|
||
// Full L2 depth + OHLCV + recent trades
|
||
perMarketMem := int64(124 * 1024) // 124KB per market
|
||
total := perMarketMem * int64(numMarkets)
|
||
|
||
fmt.Println("\n2. MARKET DATA CACHE")
|
||
fmt.Printf(" L2 Depth (100 levels): 3.2 KB per market\n")
|
||
fmt.Printf(" OHLCV bars (1440 × 1min): 46 KB per market\n")
|
||
fmt.Printf(" Recent trades (1000): 74 KB per market\n")
|
||
fmt.Printf(" Total per market: 124 KB\n")
|
||
fmt.Printf(" Total: %s\n", formatBytes(total))
|
||
|
||
return total
|
||
}
|
||
|
||
func calculateUserMemory(numUsers int) int64 {
|
||
// Core user account data
|
||
baseUserSize := int64(2048) // 2KB base structure
|
||
|
||
// Assume 20% very active, 30% active, 50% occasional
|
||
veryActive := int64(numUsers) * 20 / 100
|
||
active := int64(numUsers) * 30 / 100
|
||
occasional := int64(numUsers) * 50 / 100
|
||
|
||
// Different memory footprints
|
||
veryActiveMem := veryActive * baseUserSize * 10 // 20KB each
|
||
activeMem := active * baseUserSize * 5 // 10KB each
|
||
occasionalMem := occasional * baseUserSize // 2KB each
|
||
|
||
total := veryActiveMem + activeMem + occasionalMem
|
||
|
||
fmt.Println("\n3. USER ACCOUNTS")
|
||
fmt.Printf(" Very active (20%%): %s users × 20 KB\n", formatNumber(int(veryActive)))
|
||
fmt.Printf(" Active (30%%): %s users × 10 KB\n", formatNumber(int(active)))
|
||
fmt.Printf(" Occasional (50%%): %s users × 2 KB\n", formatNumber(int(occasional)))
|
||
fmt.Printf(" Total: %s\n", formatBytes(total))
|
||
|
||
return total
|
||
}
|
||
|
||
func calculatePositionsMemory(numUsers int) int64 {
|
||
// Assume 10% of users have open positions
|
||
activeTraders := int64(numUsers) * 10 / 100
|
||
avgPositionsPerUser := int64(5)
|
||
bytesPerPosition := int64(82)
|
||
|
||
total := activeTraders * avgPositionsPerUser * bytesPerPosition
|
||
|
||
fmt.Println("\n4. ACTIVE POSITIONS")
|
||
fmt.Printf(" Active traders (10%%): %s\n", formatNumber(int(activeTraders)))
|
||
fmt.Printf(" Avg positions per trader: %d\n", avgPositionsPerUser)
|
||
fmt.Printf(" Memory per position: 82 bytes\n")
|
||
fmt.Printf(" Total: %s\n", formatBytes(total))
|
||
|
||
return total
|
||
}
|
||
|
||
func calculateMarginMemory(numUsers int) int64 {
|
||
// 5% of users use margin
|
||
marginUsers := int64(numUsers) * 5 / 100
|
||
marginAccountSize := int64(500) // Including maps and history
|
||
|
||
total := marginUsers * marginAccountSize
|
||
|
||
fmt.Println("\n5. MARGIN SYSTEM")
|
||
fmt.Printf(" Margin users (5%%): %s\n", formatNumber(int(marginUsers)))
|
||
fmt.Printf(" Memory per margin account: 500 bytes\n")
|
||
fmt.Printf(" Total: %s\n", formatBytes(total))
|
||
|
||
return total
|
||
}
|
||
|
||
func calculateVaultMemory(numVaults, numUsers int) int64 {
|
||
// 2% of users participate in vaults
|
||
vaultUsers := int64(numUsers) * 2 / 100
|
||
avgVaultsPerUser := int64(2)
|
||
bytesPerVaultPosition := int64(88)
|
||
|
||
// Vault strategy data
|
||
vaultStrategyMem := int64(numVaults) * 100 * 1024 // 100KB per vault
|
||
|
||
// User positions
|
||
userVaultMem := vaultUsers * avgVaultsPerUser * bytesPerVaultPosition
|
||
|
||
total := vaultStrategyMem + userVaultMem
|
||
|
||
fmt.Println("\n6. VAULTS")
|
||
fmt.Printf(" Vault strategies: %d × 100 KB\n", numVaults)
|
||
fmt.Printf(" Vault participants (2%%): %s\n", formatNumber(int(vaultUsers)))
|
||
fmt.Printf(" Avg vaults per user: %d\n", avgVaultsPerUser)
|
||
fmt.Printf(" Total: %s\n", formatBytes(total))
|
||
|
||
return total
|
||
}
|
||
|
||
func calculateSettlementMemory(numUsers int) int64 {
|
||
// Active settlements in memory (last 24h)
|
||
avgSettlementsPerDay := int64(numUsers) * 10 / 100 // 10% of users trade daily
|
||
settlementSize := int64(150) // Including netting
|
||
|
||
total := avgSettlementsPerDay * settlementSize
|
||
|
||
fmt.Println("\n7. SETTLEMENT ENGINE")
|
||
fmt.Printf(" Daily settlements: %s\n", formatNumber(int(avgSettlementsPerDay)))
|
||
fmt.Printf(" Memory per settlement: 150 bytes\n")
|
||
fmt.Printf(" Total: %s\n", formatBytes(total))
|
||
|
||
return total
|
||
}
|
||
|
||
func calculateRiskMemory(numUsers int) int64 {
|
||
// Risk profiles for active traders
|
||
activeTraders := int64(numUsers) * 10 / 100
|
||
riskProfileSize := int64(200) // Including history
|
||
|
||
total := activeTraders * riskProfileSize
|
||
|
||
fmt.Println("\n8. RISK MANAGEMENT")
|
||
fmt.Printf(" Active traders (10%%): %s\n", formatNumber(int(activeTraders)))
|
||
fmt.Printf(" Memory per risk profile: 200 bytes\n")
|
||
fmt.Printf(" Total: %s\n", formatBytes(total))
|
||
|
||
return total
|
||
}
|
||
|
||
func calculateSessionMemory(numUsers int) int64 {
|
||
// Assume 5% concurrent users
|
||
concurrentUsers := int64(numUsers) * 5 / 100
|
||
sessionSize := int64(200)
|
||
|
||
total := concurrentUsers * sessionSize
|
||
|
||
fmt.Println("\n9. SESSION MANAGEMENT")
|
||
fmt.Printf(" Concurrent users (5%%): %s\n", formatNumber(int(concurrentUsers)))
|
||
fmt.Printf(" Memory per session: 200 bytes\n")
|
||
fmt.Printf(" Total: %s\n", formatBytes(total))
|
||
|
||
return total
|
||
}
|
||
|
||
func calculateTradeHistoryMemory(numUsers int) int64 {
|
||
// Last 100 trades per active user
|
||
activeTraders := int64(numUsers) * 10 / 100
|
||
tradesPerUser := int64(100)
|
||
tradeSize := int64(74)
|
||
|
||
total := activeTraders * tradesPerUser * tradeSize
|
||
|
||
fmt.Println("\n10. TRADE HISTORY")
|
||
fmt.Printf(" Active traders (10%%): %s\n", formatNumber(int(activeTraders)))
|
||
fmt.Printf(" Trades per user: %d\n", tradesPerUser)
|
||
fmt.Printf(" Memory per trade: 74 bytes\n")
|
||
fmt.Printf(" Total: %s\n", formatBytes(total))
|
||
|
||
return total
|
||
}
|
||
|
||
func formatBytes(bytes int64) string {
|
||
if bytes < 1024 {
|
||
return fmt.Sprintf("%d B", bytes)
|
||
} else if bytes < 1024*1024 {
|
||
return fmt.Sprintf("%.2f KB", float64(bytes)/1024)
|
||
} else if bytes < 1024*1024*1024 {
|
||
return fmt.Sprintf("%.2f MB", float64(bytes)/(1024*1024))
|
||
} else {
|
||
return fmt.Sprintf("%.2f GB", float64(bytes)/(1024*1024*1024))
|
||
}
|
||
}
|
||
|
||
func formatNumber(n int) string {
|
||
if n < 1000 {
|
||
return fmt.Sprintf("%d", n)
|
||
} else if n < 1000000 {
|
||
return fmt.Sprintf("%.1fK", float64(n)/1000)
|
||
} else if n < 1000000000 {
|
||
return fmt.Sprintf("%.1fM", float64(n)/1000000)
|
||
} else {
|
||
return fmt.Sprintf("%.1fB", float64(n)/1000000000)
|
||
}
|
||
}
|