Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions data/transactions/verify/verifiedTxnCache.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import (
"github.com/algorand/go-algorand/protocol"
)

const entriesPerBucket = 8179 // the default bucket size; a prime number could promote a lower hash collisions in case the hash function isn't perfect.
const maxPinnedEntries = 500000

// VerifiedTxnCacheError helps to identify the errors of a cache error and diffrenciate these from a general verification errors.
Expand Down Expand Up @@ -72,6 +71,8 @@ type VerifiedTransactionCache interface {

// verifiedTransactionCache provides an implementation of the VerifiedTransactionCache interface
type verifiedTransactionCache struct {
// Number of entries in each map (bucket).
entriesPerBucket int
// bucketsLock is the lock for syncornizing the access to the cache
bucketsLock deadlock.Mutex
// buckets is the circular cache buckets buffer
Expand All @@ -84,14 +85,14 @@ type verifiedTransactionCache struct {

// MakeVerifiedTransactionCache creates an instance of verifiedTransactionCache and returns it.
func MakeVerifiedTransactionCache(cacheSize int) VerifiedTransactionCache {
bucketsCount := 1 + (cacheSize / entriesPerBucket)
impl := &verifiedTransactionCache{
buckets: make([]map[transactions.Txid]*GroupContext, bucketsCount),
pinned: make(map[transactions.Txid]*GroupContext, cacheSize),
base: 0,
entriesPerBucket: (cacheSize + 1) / 2,
buckets: make([]map[transactions.Txid]*GroupContext, 3),
pinned: make(map[transactions.Txid]*GroupContext, cacheSize),
base: 0,
}
for i := 0; i < bucketsCount; i++ {
impl.buckets[i] = make(map[transactions.Txid]*GroupContext, entriesPerBucket)
for i := 0; i < len(impl.buckets); i++ {
impl.buckets[i] = make(map[transactions.Txid]*GroupContext, impl.entriesPerBucket)
}
return impl
}
Expand Down Expand Up @@ -245,10 +246,10 @@ func (v *verifiedTransactionCache) Pin(txgroup []transactions.SignedTxn) (err er

// add is the internal implementation of Add/AddPayset which adds a transaction group to the buffer.
func (v *verifiedTransactionCache) add(txgroup []transactions.SignedTxn, groupCtx *GroupContext) {
if len(v.buckets[v.base])+len(txgroup) > entriesPerBucket {
if len(v.buckets[v.base])+len(txgroup) > v.entriesPerBucket {
// move to the next bucket while deleting the content of the next bucket.
v.base = (v.base + 1) % len(v.buckets)
v.buckets[v.base] = make(map[transactions.Txid]*GroupContext, entriesPerBucket)
v.buckets[v.base] = make(map[transactions.Txid]*GroupContext, v.entriesPerBucket)
}
currentBucket := v.buckets[v.base]
for _, txn := range txgroup {
Expand Down
12 changes: 6 additions & 6 deletions data/transactions/verify/verifiedTxnCache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ func TestBucketCycling(t *testing.T) {
partitiontest.PartitionTest(t)

bucketCount := 3
icache := MakeVerifiedTransactionCache(entriesPerBucket * bucketCount)
entriesPerBucket := 100
icache := MakeVerifiedTransactionCache(entriesPerBucket * (bucketCount - 1))
impl := icache.(*verifiedTransactionCache)
_, signedTxn, _, _ := generateTestObjects(entriesPerBucket*bucketCount*2, bucketCount, 0)

Expand All @@ -58,7 +59,7 @@ func TestBucketCycling(t *testing.T) {
require.NoError(t, err)

// fill up the cache with entries.
for i := 0; i < entriesPerBucket*(bucketCount+1); i++ {
for i := 0; i < entriesPerBucket*bucketCount; i++ {
impl.Add([]transactions.SignedTxn{signedTxn[i]}, groupCtx)
// test to see that the base is sliding when bucket get filled up.
require.Equal(t, i/entriesPerBucket, impl.base)
Expand Down Expand Up @@ -136,13 +137,13 @@ func BenchmarkGetUnverifiedTranscationGroups50(b *testing.B) {
func TestUpdatePinned(t *testing.T) {
partitiontest.PartitionTest(t)

size := entriesPerBucket
size := 100
icache := MakeVerifiedTransactionCache(size * 10)
impl := icache.(*verifiedTransactionCache)
_, signedTxn, secrets, addrs := generateTestObjects(size*2, 10, 0)
txnGroups := generateTransactionGroups(signedTxn, secrets, addrs)

// insert half of the entries.
// insert some entries.
for i := 0; i < len(txnGroups); i++ {
groupCtx, _ := PrepareGroupContext(txnGroups[i], blockHeader)
impl.Add(txnGroups[i], groupCtx)
Expand All @@ -165,7 +166,7 @@ func TestUpdatePinned(t *testing.T) {
func TestPinningTransactions(t *testing.T) {
partitiontest.PartitionTest(t)

size := entriesPerBucket
size := 100
icache := MakeVerifiedTransactionCache(size)
impl := icache.(*verifiedTransactionCache)
_, signedTxn, secrets, addrs := generateTestObjects(size*2, 10, 0)
Expand All @@ -182,5 +183,4 @@ func TestPinningTransactions(t *testing.T) {

// try to pin an entry that was not added.
require.Error(t, impl.Pin(txnGroups[len(txnGroups)-1]))

}