Skip to content

perf(txmetacache): optimize memory usage by 4.62 GB#475

Open
freemans13 wants to merge 5 commits intobsv-blockchain:mainfrom
freemans13:optimize-txmetacache-memory
Open

perf(txmetacache): optimize memory usage by 4.62 GB#475
freemans13 wants to merge 5 commits intobsv-blockchain:mainfrom
freemans13:optimize-txmetacache-memory

Conversation

@freemans13
Copy link
Collaborator

Summary

This PR implements two memory optimizations for the txmetacache, saving 4.62 GB at 770M transactions:

1. Remove Dead Height-Based Expiry Code (3.08 GB saved)

  • Removed appendHeightToValue() function that added 4-byte height suffix
  • The height was never read or checked - pure dead code
  • Removed noOfBlocksToKeepInTxMetaCache field and hitOldTx metric
  • Production always reaches capacity before expiry timeout

2. Optimize Key Encoding (1.54 GB saved)

  • Transaction hashes are always 32 bytes, removed redundant 2-byte key length prefix
  • Changed encoding: [2B:keyLen][2B:valLen][key][val][2B:valLen][32B:key][val]
  • Updated all 3 bucket implementations (unallocated, preallocated, trimmed)

Memory Impact (at 770M transactions)

Before: ~95.4 GB total
After:  ~90.8 GB total
Saved:   4.62 GB (4.8% reduction)

Testing

  • ✅ Main test suites passing (TestImprovedCache_SetAndGet, etc.)
  • ✅ Code compiles without errors
  • ✅ Git pre-commit hooks passed
  • ⚠️ A few specialized tests need updates (they use non-32-byte keys)

Breaking Changes

  • Cache now only accepts 32-byte keys (transaction hashes)
  • Old cached data with different encoding will be invalid (cache will rebuild on restart)

Performance Impact

  • Reduced memory footprint by 4.62 GB
  • No CPU or throughput regressions expected
  • Slightly faster encoding/decoding (2 bytes less per entry)

🤖 Generated with Claude Code

freemans13 and others added 2 commits February 4, 2026 20:30
…y length prefix

This commit implements two memory optimizations for the txmetacache:

1. **Remove dead height-based expiry code (3.08 GB savings)**
   - Removed appendHeightToValue function that appended 4-byte height suffix
   - The height was never read or checked, making it pure overhead
   - Removed noOfBlocksToKeepInTxMetaCache field and related configuration
   - Removed hitOldTx metric (never incremented)
   - Updated misleading comments about height-based expiry
   - Production always reaches capacity before expiry timeout

2. **Optimize key encoding by removing key length prefix (1.54 GB savings)**
   - Transaction hashes are always 32 bytes, so key length prefix is redundant
   - Changed encoding format from [2B:keyLen][2B:valLen][key][val]
     to [2B:valLen][32B:key][val]
   - Updated all three bucket implementations:
     * bucketUnallocated.Set/Get
     * bucketPreallocated.Set/Get
     * bucketTrimmed.Set/Get
   - Keys must now be exactly 32 bytes (enforced with validation)

**Memory savings at 770M transactions:**
- Removed height suffix: 4 bytes × 770M = 3.08 GB
- Removed key length: 2 bytes × 770M = 1.54 GB
- **Total: 4.62 GB saved** (from ~95GB → ~90GB)

**Testing:**
- Updated test cases to use 32-byte keys (via makeKey32 helper)
- Main test suites passing (TestImprovedCache_SetAndGet, etc.)
- Some specialized tests need updates for 32-byte key requirement

**Breaking changes:**
- Cache now only accepts 32-byte keys (transaction hashes)
- Old cached data with different encoding will be invalid (cache will be rebuilt)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Updated TestImprovedCache_TestSetMultiWithExpectedMisses capacity calculation
- Fixed all tests to use makeKey32() helper for 32-byte keys
- Updated TestImprovedCache_LargeKeys to test key size validation
- Fixed TestImprovedCache_EdgeCases to expect empty key rejection
- Fixed Test_txMetaCache_MultiOperations for removed height encoding

All ImprovedCache and txMetaCache tests now passing.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@github-actions
Copy link
Contributor

github-actions bot commented Feb 4, 2026

🤖 Claude Code Review

Status: Complete

Current Review:
No critical issues found.

The boundary check issue from the previous review has been fixed - all three bucket implementations now correctly use > instead of >= when validating idx+keyLen+valLen > ChunkSize.

Minor documentation cleanup needed:

  • Line 8 of txmetacache.go: Package comment still mentions height-based expiration but this feature has been removed
  • Lines 647-657 of txmetacache.go: Orphaned comment block for removed appendHeightToValue function should be deleted

These are documentation-only issues that do not affect functionality.


History:

  • Fixed: Boundary check off-by-one error (changed >= to > in three locations)

valLen := (uint64(vLenBuf[0]) << 8) | uint64(vLenBuf[1])
idx += 2

if idx+keyLen+valLen >= ChunkSize {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The boundary check logic has an off-by-one error.

Issue: After incrementing idx by 2, this check validates whether we can read keyLen+valLen bytes starting at idx. However, using >= is too strict.

Analysis:

  • Valid chunk indices: 0 to ChunkSize-1
  • After reading 2-byte value length, idx points to the key
  • We need to read bytes from idx to idx+keyLen+valLen-1
  • The last byte at idx+keyLen+valLen-1 must be < ChunkSize
  • Therefore: idx+keyLen+valLen-1 < ChunkSize, which means idx+keyLen+valLen ≤ ChunkSize

Example (ChunkSize=100):

  • If idx=65, keyLen=32, valLen=3, then idx+keyLen+valLen=100
  • Current code: 100 >= 100 → rejects (incorrect)
  • Should read bytes 65-96 (key) and 97-99 (value), which are all valid

Fix: Change >= to > on lines 917, 1303, and 1608:

if idx+keyLen+valLen > ChunkSize {

This affects all three bucket implementations.

freemans13 and others added 2 commits February 4, 2026 21:27
- Fix gci import ordering in improved_cache.go and improved_cache_test.go
- Add nolint:gosec comments for vLenBuf[1] accesses (false positives on fixed-size array)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@sonarqubecloud
Copy link

sonarqubecloud bot commented Feb 4, 2026

Quality Gate Failed Quality Gate failed

Failed conditions
40.3% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

@freemans13 freemans13 self-assigned this Feb 4, 2026
@gokutheengineer gokutheengineer self-requested a review February 5, 2026 13:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant