Skip to content

Instantly share code, notes, and snippets.

@thepaul
Created June 14, 2022 23:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thepaul/8804bcf2710449ae524b16967f967687 to your computer and use it in GitHub Desktop.
Save thepaul/8804bcf2710449ae524b16967f967687 to your computer and use it in GitHub Desktop.
Calculating memory usage of reputation writecache
package main
import (
"sync"
"time"
"unsafe"
"golang.org/x/text/language"
"golang.org/x/text/message"
)
type NodeID [32]byte
type AuditWindow struct {
Start time.Time
OnlineCount int32
TotalCount int32
nul struct{}
unrecog []byte
sizecache int32
}
type AuditHistory struct {
Windows []*AuditWindow
Score float64
nul struct{}
unrecog []byte
sizecache int32
}
type Mutations struct {
successes int
failures int
unknowns int
offlines int
history *AuditHistory
}
type cachedNodeReputationInfo struct {
nodeID NodeID
entryLock sync.Mutex
info *Info
syncError error
errorRetryAt time.Time
syncAt time.Time
mutations Mutations
}
type Info struct {
AuditSuccessCount int64
TotalAuditCount int64
VettedAt *time.Time
UnknownAuditSuspended *time.Time
OfflineSuspended *time.Time
UnderReview *time.Time
Disqualified *time.Time
DisqualificationReason int
OnlineScore float64
AuditHistory *AuditHistory
AuditReputationAlpha float64
AuditReputationBeta float64
UnknownAuditReputationAlpha float64
UnknownAuditReputationBeta float64
}
func main() {
const (
// release defaults
windowSize = 12 * time.Hour
flushInterval = 2 * time.Hour
trackingPeriod = 720 * time.Hour
// this number is an example; adjust to the appropriate scenario
expectedNumActiveNodes = 15000 // nodes which are holding pieces
expectedNumWindowsInMutations = (flushInterval + windowSize - 1) / windowSize // how many windows are needed to cover a FlushInterval, rounded up
expectedNumWindowsInInfo = trackingPeriod / windowSize // this is the maximum, expected near the end of a TrackingPeriod
)
p := message.NewPrinter(language.English)
auditWindowSize := unsafe.Sizeof(AuditWindow{})
infoBaseSize := unsafe.Sizeof(Info{}) + 5*unsafe.Sizeof(time.Time{}) + unsafe.Sizeof(AuditHistory{})
infoSize := infoBaseSize + uintptr(expectedNumWindowsInInfo)*auditWindowSize
entryBaseSize := unsafe.Sizeof(cachedNodeReputationInfo{}) + unsafe.Sizeof(AuditHistory{})
entrySize := entryBaseSize + infoSize + uintptr(expectedNumWindowsInMutations)*auditWindowSize
p.Printf("%5dB (%d + %d * %d) per Info record\n", infoSize, infoBaseSize, expectedNumWindowsInInfo, auditWindowSize)
p.Printf("%5dB (%d + %d + %d * %d) per node\n", entrySize, entryBaseSize, infoSize, expectedNumWindowsInMutations, auditWindowSize)
p.Printf("with %d nodes, %dB total during periods of highest usage", expectedNumActiveNodes, expectedNumActiveNodes*entrySize)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment