peer: rename mruinvmap, mrunoncemap to lruinvmap, lrunoncemap

The names mean that the caches contain the Most Recently Used entries.
But they behave in a Least Recently Used fashion.
This commit is contained in:
Andrew Chiw 2018-01-18 20:56:21 +01:00 committed by Dave Collins
parent e45c34fbfc
commit 70dd37e644
5 changed files with 82 additions and 82 deletions

View File

@ -14,10 +14,10 @@ import (
"github.com/decred/dcrd/wire"
)
// mruInventoryMap provides a concurrency safe map that is limited to a maximum
// lruInventoryMap provides a concurrency safe map that is limited to a maximum
// number of items with eviction for the oldest entry when the limit is
// exceeded.
type mruInventoryMap struct {
type lruInventoryMap struct {
invMtx sync.Mutex
invMap map[wire.InvVect]*list.Element // nearly O(1) lookups
invList *list.List // O(1) insert, update, delete
@ -27,7 +27,7 @@ type mruInventoryMap struct {
// String returns the map as a human-readable string.
//
// This function is safe for concurrent access.
func (m *mruInventoryMap) String() string {
func (m *lruInventoryMap) String() string {
m.invMtx.Lock()
defer m.invMtx.Unlock()
@ -49,7 +49,7 @@ func (m *mruInventoryMap) String() string {
// Exists returns whether or not the passed inventory item is in the map.
//
// This function is safe for concurrent access.
func (m *mruInventoryMap) Exists(iv *wire.InvVect) bool {
func (m *lruInventoryMap) Exists(iv *wire.InvVect) bool {
m.invMtx.Lock()
_, exists := m.invMap[*iv]
m.invMtx.Unlock()
@ -62,7 +62,7 @@ func (m *mruInventoryMap) Exists(iv *wire.InvVect) bool {
// item makes it the most recently used item.
//
// This function is safe for concurrent access.
func (m *mruInventoryMap) Add(iv *wire.InvVect) {
func (m *lruInventoryMap) Add(iv *wire.InvVect) {
m.invMtx.Lock()
defer m.invMtx.Unlock()
@ -105,7 +105,7 @@ func (m *mruInventoryMap) Add(iv *wire.InvVect) {
// Delete deletes the passed inventory item from the map (if it exists).
//
// This function is safe for concurrent access.
func (m *mruInventoryMap) Delete(iv *wire.InvVect) {
func (m *lruInventoryMap) Delete(iv *wire.InvVect) {
m.invMtx.Lock()
if node, exists := m.invMap[*iv]; exists {
m.invList.Remove(node)
@ -114,12 +114,12 @@ func (m *mruInventoryMap) Delete(iv *wire.InvVect) {
m.invMtx.Unlock()
}
// newMruInventoryMap returns a new inventory map that is limited to the number
// newLruInventoryMap returns a new inventory map that is limited to the number
// of entries specified by limit. When the number of entries exceeds the limit,
// the oldest (least recently used) entry will be removed to make room for the
// new entry.
func newMruInventoryMap(limit uint) *mruInventoryMap {
m := mruInventoryMap{
func newLruInventoryMap(limit uint) *lruInventoryMap {
m := lruInventoryMap{
invMap: make(map[wire.InvVect]*list.Element),
invList: list.New(),
limit: limit,

View File

@ -14,11 +14,11 @@ import (
"github.com/decred/dcrd/wire"
)
// TestMruInventoryMap ensures the MruInventoryMap behaves as expected including
// TestLruInventoryMap ensures the LruInventoryMap behaves as expected including
// limiting, eviction of least-recently used entries, specific entry removal,
// and existence tests.
func TestMruInventoryMap(t *testing.T) {
// Create a bunch of fake inventory vectors to use in testing the mru
func TestLruInventoryMap(t *testing.T) {
// Create a bunch of fake inventory vectors to use in testing the lru
// inventory code.
numInvVects := 10
invVects := make([]*wire.InvVect, 0, numInvVects)
@ -42,19 +42,19 @@ func TestMruInventoryMap(t *testing.T) {
testLoop:
for i, test := range tests {
// Create a new mru inventory map limited by the specified test
// Create a new lru inventory map limited by the specified test
// limit and add all of the test inventory vectors. This will
// cause evicition since there are more test inventory vectors
// than the limits.
mruInvMap := newMruInventoryMap(uint(test.limit))
lruInvMap := newLruInventoryMap(uint(test.limit))
for j := 0; j < numInvVects; j++ {
mruInvMap.Add(invVects[j])
lruInvMap.Add(invVects[j])
}
// Ensure the limited number of most recent entries in the
// inventory vector list exist.
for j := numInvVects - test.limit; j < numInvVects; j++ {
if !mruInvMap.Exists(invVects[j]) {
if !lruInvMap.Exists(invVects[j]) {
t.Errorf("Exists #%d (%s) entry %s does not "+
"exist", i, test.name, *invVects[j])
continue testLoop
@ -64,7 +64,7 @@ testLoop:
// Ensure the entries before the limited number of most recent
// entries in the inventory vector list do not exist.
for j := 0; j < numInvVects-test.limit; j++ {
if mruInvMap.Exists(invVects[j]) {
if lruInvMap.Exists(invVects[j]) {
t.Errorf("Exists #%d (%s) entry %s exists", i,
test.name, *invVects[j])
continue testLoop
@ -80,16 +80,16 @@ testLoop:
// This check needs at least 2 entries.
if test.limit > 1 {
origLruIndex := numInvVects - test.limit
mruInvMap.Add(invVects[origLruIndex])
lruInvMap.Add(invVects[origLruIndex])
iv := wire.NewInvVect(wire.InvTypeBlock,
&chainhash.Hash{0x00, 0x01})
mruInvMap.Add(iv)
lruInvMap.Add(iv)
// Ensure the original lru entry still exists since it
// was updated and should've have become the mru entry.
if !mruInvMap.Exists(invVects[origLruIndex]) {
t.Errorf("MRU #%d (%s) entry %s does not exist",
// was updated and should've have become the lru entry.
if !lruInvMap.Exists(invVects[origLruIndex]) {
t.Errorf("LRU #%d (%s) entry %s does not exist",
i, test.name, *invVects[origLruIndex])
continue testLoop
}
@ -97,8 +97,8 @@ testLoop:
// Ensure the entry that should've become the new lru
// entry was evicted.
newLruIndex := origLruIndex + 1
if mruInvMap.Exists(invVects[newLruIndex]) {
t.Errorf("MRU #%d (%s) entry %s exists", i,
if lruInvMap.Exists(invVects[newLruIndex]) {
t.Errorf("LRU #%d (%s) entry %s exists", i,
test.name, *invVects[newLruIndex])
continue testLoop
}
@ -108,8 +108,8 @@ testLoop:
// including those that don't exist in the map, and ensure they
// no longer exist.
for j := 0; j < numInvVects; j++ {
mruInvMap.Delete(invVects[j])
if mruInvMap.Exists(invVects[j]) {
lruInvMap.Delete(invVects[j])
if lruInvMap.Exists(invVects[j]) {
t.Errorf("Delete #%d (%s) entry %s exists", i,
test.name, *invVects[j])
continue testLoop
@ -118,38 +118,38 @@ testLoop:
}
}
// TestMruInventoryMapStringer tests the stringized output for the
// MruInventoryMap type.
func TestMruInventoryMapStringer(t *testing.T) {
// Create a couple of fake inventory vectors to use in testing the mru
// TestLruInventoryMapStringer tests the stringized output for the
// LruInventoryMap type.
func TestLruInventoryMapStringer(t *testing.T) {
// Create a couple of fake inventory vectors to use in testing the lru
// inventory stringer code.
hash1 := &chainhash.Hash{0x01}
hash2 := &chainhash.Hash{0x02}
iv1 := wire.NewInvVect(wire.InvTypeBlock, hash1)
iv2 := wire.NewInvVect(wire.InvTypeBlock, hash2)
// Create new mru inventory map and add the inventory vectors.
mruInvMap := newMruInventoryMap(uint(2))
mruInvMap.Add(iv1)
mruInvMap.Add(iv2)
// Create new lru inventory map and add the inventory vectors.
lruInvMap := newLruInventoryMap(uint(2))
lruInvMap.Add(iv1)
lruInvMap.Add(iv2)
// Ensure the stringer gives the expected result. Since map iteration
// is not ordered, either entry could be first, so account for both
// cases.
wantStr1 := fmt.Sprintf("<%d>[%s, %s]", 2, *iv1, *iv2)
wantStr2 := fmt.Sprintf("<%d>[%s, %s]", 2, *iv2, *iv1)
gotStr := mruInvMap.String()
gotStr := lruInvMap.String()
if gotStr != wantStr1 && gotStr != wantStr2 {
t.Fatalf("unexpected string representation - got %q, want %q "+
"or %q", gotStr, wantStr1, wantStr2)
}
}
// BenchmarkMruInventoryList performs basic benchmarks on the most recently
// BenchmarkLruInventoryList performs basic benchmarks on the most recently
// used inventory handling.
func BenchmarkMruInventoryList(b *testing.B) {
func BenchmarkLruInventoryList(b *testing.B) {
// Create a bunch of fake inventory vectors to use in benchmarking
// the mru inventory code.
// the lru inventory code.
b.StopTimer()
numInvVects := 100000
invVects := make([]*wire.InvVect, 0, numInvVects)
@ -164,8 +164,8 @@ func BenchmarkMruInventoryList(b *testing.B) {
// Benchmark the add plus evicition code.
limit := 20000
mruInvMap := newMruInventoryMap(uint(limit))
lruInvMap := newLruInventoryMap(uint(limit))
for i := 0; i < b.N; i++ {
mruInvMap.Add(invVects[i%numInvVects])
lruInvMap.Add(invVects[i%numInvVects])
}
}

View File

@ -12,10 +12,10 @@ import (
"sync"
)
// mruNonceMap provides a concurrency safe map that is limited to a maximum
// lruNonceMap provides a concurrency safe map that is limited to a maximum
// number of items with eviction for the oldest entry when the limit is
// exceeded.
type mruNonceMap struct {
type lruNonceMap struct {
mtx sync.Mutex
nonceMap map[uint64]*list.Element // nearly O(1) lookups
nonceList *list.List // O(1) insert, update, delete
@ -25,7 +25,7 @@ type mruNonceMap struct {
// String returns the map as a human-readable string.
//
// This function is safe for concurrent access.
func (m *mruNonceMap) String() string {
func (m *lruNonceMap) String() string {
m.mtx.Lock()
defer m.mtx.Unlock()
@ -47,7 +47,7 @@ func (m *mruNonceMap) String() string {
// Exists returns whether or not the passed nonce is in the map.
//
// This function is safe for concurrent access.
func (m *mruNonceMap) Exists(nonce uint64) bool {
func (m *lruNonceMap) Exists(nonce uint64) bool {
m.mtx.Lock()
_, exists := m.nonceMap[nonce]
m.mtx.Unlock()
@ -60,7 +60,7 @@ func (m *mruNonceMap) Exists(nonce uint64) bool {
// makes it the most recently used item.
//
// This function is safe for concurrent access.
func (m *mruNonceMap) Add(nonce uint64) {
func (m *lruNonceMap) Add(nonce uint64) {
m.mtx.Lock()
defer m.mtx.Unlock()
@ -103,7 +103,7 @@ func (m *mruNonceMap) Add(nonce uint64) {
// Delete deletes the passed nonce from the map (if it exists).
//
// This function is safe for concurrent access.
func (m *mruNonceMap) Delete(nonce uint64) {
func (m *lruNonceMap) Delete(nonce uint64) {
m.mtx.Lock()
if node, exists := m.nonceMap[nonce]; exists {
m.nonceList.Remove(node)
@ -112,12 +112,12 @@ func (m *mruNonceMap) Delete(nonce uint64) {
m.mtx.Unlock()
}
// newMruNonceMap returns a new nonce map that is limited to the number of
// newLruNonceMap returns a new nonce map that is limited to the number of
// entries specified by limit. When the number of entries exceeds the limit,
// the oldest (least recently used) entry will be removed to make room for the
// new entry.
func newMruNonceMap(limit uint) *mruNonceMap {
m := mruNonceMap{
func newLruNonceMap(limit uint) *lruNonceMap {
m := lruNonceMap{
nonceMap: make(map[uint64]*list.Element),
nonceList: list.New(),
limit: limit,

View File

@ -10,11 +10,11 @@ import (
"testing"
)
// TestMruNonceMap ensures the mruNonceMap behaves as expected including
// TestLruNonceMap ensures the lruNonceMap behaves as expected including
// limiting, eviction of least-recently used entries, specific entry removal,
// and existence tests.
func TestMruNonceMap(t *testing.T) {
// Create a bunch of fake nonces to use in testing the mru nonce code.
func TestLruNonceMap(t *testing.T) {
// Create a bunch of fake nonces to use in testing the lru nonce code.
numNonces := 10
nonces := make([]uint64, 0, numNonces)
for i := 0; i < numNonces; i++ {
@ -35,18 +35,18 @@ func TestMruNonceMap(t *testing.T) {
testLoop:
for i, test := range tests {
// Create a new mru nonce map limited by the specified test
// Create a new lru nonce map limited by the specified test
// limit and add all of the test nonces. This will cause
// evicition since there are more test nonces than the limits.
mruNonceMap := newMruNonceMap(uint(test.limit))
lruNonceMap := newLruNonceMap(uint(test.limit))
for j := 0; j < numNonces; j++ {
mruNonceMap.Add(nonces[j])
lruNonceMap.Add(nonces[j])
}
// Ensure the limited number of most recent entries in the list
// exist.
for j := numNonces - test.limit; j < numNonces; j++ {
if !mruNonceMap.Exists(nonces[j]) {
if !lruNonceMap.Exists(nonces[j]) {
t.Errorf("Exists #%d (%s) entry %d does not "+
"exist", i, test.name, nonces[j])
continue testLoop
@ -56,7 +56,7 @@ testLoop:
// Ensure the entries before the limited number of most recent
// entries in the list do not exist.
for j := 0; j < numNonces-test.limit; j++ {
if mruNonceMap.Exists(nonces[j]) {
if lruNonceMap.Exists(nonces[j]) {
t.Errorf("Exists #%d (%s) entry %d exists", i,
test.name, nonces[j])
continue testLoop
@ -72,14 +72,14 @@ testLoop:
// This check needs at least 2 entries.
if test.limit > 1 {
origLruIndex := numNonces - test.limit
mruNonceMap.Add(nonces[origLruIndex])
lruNonceMap.Add(nonces[origLruIndex])
mruNonceMap.Add(uint64(numNonces) + 1)
lruNonceMap.Add(uint64(numNonces) + 1)
// Ensure the original lru entry still exists since it
// was updated and should've have become the mru entry.
if !mruNonceMap.Exists(nonces[origLruIndex]) {
t.Errorf("MRU #%d (%s) entry %d does not exist",
// was updated and should've have become the lru entry.
if !lruNonceMap.Exists(nonces[origLruIndex]) {
t.Errorf("LRU #%d (%s) entry %d does not exist",
i, test.name, nonces[origLruIndex])
continue testLoop
}
@ -87,8 +87,8 @@ testLoop:
// Ensure the entry that should've become the new lru
// entry was evicted.
newLruIndex := origLruIndex + 1
if mruNonceMap.Exists(nonces[newLruIndex]) {
t.Errorf("MRU #%d (%s) entry %d exists", i,
if lruNonceMap.Exists(nonces[newLruIndex]) {
t.Errorf("LRU #%d (%s) entry %d exists", i,
test.name, nonces[newLruIndex])
continue testLoop
}
@ -97,8 +97,8 @@ testLoop:
// Delete all of the entries in the list, including those that
// don't exist in the map, and ensure they no longer exist.
for j := 0; j < numNonces; j++ {
mruNonceMap.Delete(nonces[j])
if mruNonceMap.Exists(nonces[j]) {
lruNonceMap.Delete(nonces[j])
if lruNonceMap.Exists(nonces[j]) {
t.Errorf("Delete #%d (%s) entry %d exists", i,
test.name, nonces[j])
continue testLoop
@ -107,34 +107,34 @@ testLoop:
}
}
// TestMruNonceMapStringer tests the stringized output for the mruNonceMap type.
func TestMruNonceMapStringer(t *testing.T) {
// Create a couple of fake nonces to use in testing the mru nonce
// TestLruNonceMapStringer tests the stringized output for the lruNonceMap type.
func TestLruNonceMapStringer(t *testing.T) {
// Create a couple of fake nonces to use in testing the lru nonce
// stringer code.
nonce1 := uint64(10)
nonce2 := uint64(20)
// Create new mru nonce map and add the nonces.
mruNonceMap := newMruNonceMap(uint(2))
mruNonceMap.Add(nonce1)
mruNonceMap.Add(nonce2)
// Create new lru nonce map and add the nonces.
lruNonceMap := newLruNonceMap(uint(2))
lruNonceMap.Add(nonce1)
lruNonceMap.Add(nonce2)
// Ensure the stringer gives the expected result. Since map iteration
// is not ordered, either entry could be first, so account for both
// cases.
wantStr1 := fmt.Sprintf("<%d>[%d, %d]", 2, nonce1, nonce2)
wantStr2 := fmt.Sprintf("<%d>[%d, %d]", 2, nonce2, nonce1)
gotStr := mruNonceMap.String()
gotStr := lruNonceMap.String()
if gotStr != wantStr1 && gotStr != wantStr2 {
t.Fatalf("unexpected string representation - got %q, want %q "+
"or %q", gotStr, wantStr1, wantStr2)
}
}
// BenchmarkMruNonceList performs basic benchmarks on the most recently used
// BenchmarkLruNonceList performs basic benchmarks on the most recently used
// nonce handling.
func BenchmarkMruNonceList(b *testing.B) {
// Create a bunch of fake nonces to use in benchmarking the mru nonce
func BenchmarkLruNonceList(b *testing.B) {
// Create a bunch of fake nonces to use in benchmarking the lru nonce
// code.
b.StopTimer()
numNonces := 100000
@ -146,8 +146,8 @@ func BenchmarkMruNonceList(b *testing.B) {
// Benchmark the add plus evicition code.
limit := 20000
mruNonceMap := newMruNonceMap(uint(limit))
lruNonceMap := newLruNonceMap(uint(limit))
for i := 0; i < b.N; i++ {
mruNonceMap.Add(nonces[i%numNonces])
lruNonceMap.Add(nonces[i%numNonces])
}
}

View File

@ -78,7 +78,7 @@ var (
// sentNonces houses the unique nonces that are generated when pushing
// version messages that are used to detect self connections.
sentNonces = newMruNonceMap(50)
sentNonces = newLruNonceMap(50)
// allowSelfConns is only used to allow the tests to bypass the self
// connection detecting and disconnect logic since they intentionally
@ -414,7 +414,7 @@ type Peer struct {
versionSent bool
verAckReceived bool
knownInventory *mruInventoryMap
knownInventory *lruInventoryMap
prevGetBlocksMtx sync.Mutex
prevGetBlocksBegin *chainhash.Hash
prevGetBlocksStop *chainhash.Hash
@ -2035,7 +2035,7 @@ func newPeerBase(cfg *Config, inbound bool) *Peer {
p := Peer{
inbound: inbound,
knownInventory: newMruInventoryMap(maxKnownInventory),
knownInventory: newLruInventoryMap(maxKnownInventory),
stallControl: make(chan stallControlMsg, 1), // nonblocking sync
outputQueue: make(chan outMsg, outputBufferSize),
sendQueue: make(chan outMsg, 1), // nonblocking sync