Commit 0a7c9b7c authored by Kirill Smelkov's avatar Kirill Smelkov

X LRU reorder works ok

parent e65a19bc
...@@ -126,7 +126,6 @@ func (c *Cache) Load(xid zodb.Xid) (data []byte, serial zodb.Tid, err error) { ...@@ -126,7 +126,6 @@ func (c *Cache) Load(xid zodb.Xid) (data []byte, serial zodb.Tid, err error) {
// rce is already in cache - use it // rce is already in cache - use it
if !rceNew { if !rceNew {
//panic(0)
<-rce.ready <-rce.ready
c.gcMu.Lock() c.gcMu.Lock()
rce.inLRU.MoveBefore(&c.lru) rce.inLRU.MoveBefore(&c.lru)
...@@ -161,7 +160,8 @@ func (c *Cache) Load(xid zodb.Xid) (data []byte, serial zodb.Tid, err error) { ...@@ -161,7 +160,8 @@ func (c *Cache) Load(xid zodb.Xid) (data []byte, serial zodb.Tid, err error) {
func (c *Cache) Prefetch(xid zodb.Xid) { func (c *Cache) Prefetch(xid zodb.Xid) {
rce, rceNew := c.lookupRCE(xid) rce, rceNew := c.lookupRCE(xid)
// XXX!rceNew -> adjust LRU? // !rceNew -> no need to adjust LRU - it will be adjusted by further actual data Load
// XXX or it is better to adjust LRU here too?
// spawn loading in the background if rce was not yet loaded // spawn loading in the background if rce was not yet loaded
if rceNew { if rceNew {
......
...@@ -221,6 +221,7 @@ func TestCache(t *testing.T) { ...@@ -221,6 +221,7 @@ func TestCache(t *testing.T) {
ok1(len(oce1.rcev) == 1) ok1(len(oce1.rcev) == 1)
ok1(oce1.rcev[0] == rce1_b4) ok1(oce1.rcev[0] == rce1_b4)
checkRCE(rce1_b4, 4, 0, nil, &zodb.ErrXidMissing{xidlt(1,4)}) checkRCE(rce1_b4, 4, 0, nil, &zodb.ErrXidMissing{xidlt(1,4)})
checkMRU(rce1_b4)
// load <6 -> new rce entry with data // load <6 -> new rce entry with data
checkLoad(xidlt(1,6), hello, 4, nil) checkLoad(xidlt(1,6), hello, 4, nil)
...@@ -228,10 +229,12 @@ func TestCache(t *testing.T) { ...@@ -228,10 +229,12 @@ func TestCache(t *testing.T) {
rce1_b6 := oce1.rcev[1] rce1_b6 := oce1.rcev[1]
checkRCE(rce1_b6, 6, 4, hello, nil) checkRCE(rce1_b6, 6, 4, hello, nil)
checkOCE(1, rce1_b4, rce1_b6) checkOCE(1, rce1_b4, rce1_b6)
checkMRU(rce1_b6, rce1_b4)
// load <5 -> <5 merged with <6 // load <5 -> <5 merged with <6
checkLoad(xidlt(1,5), hello, 4, nil) checkLoad(xidlt(1,5), hello, 4, nil)
checkOCE(1, rce1_b4, rce1_b6) checkOCE(1, rce1_b4, rce1_b6)
checkMRU(rce1_b6, rce1_b4)
// load <7 -> <6 merged with <7 // load <7 -> <6 merged with <7
checkLoad(xidlt(1,7), hello, 4, nil) checkLoad(xidlt(1,7), hello, 4, nil)
...@@ -240,6 +243,7 @@ func TestCache(t *testing.T) { ...@@ -240,6 +243,7 @@ func TestCache(t *testing.T) {
ok1(rce1_b7 != rce1_b6) ok1(rce1_b7 != rce1_b6)
checkRCE(rce1_b7, 7, 4, hello, nil) checkRCE(rce1_b7, 7, 4, hello, nil)
checkOCE(1, rce1_b4, rce1_b7) checkOCE(1, rce1_b4, rce1_b7)
checkMRU(rce1_b7, rce1_b4)
// load <8 -> ioerr + new rce // load <8 -> ioerr + new rce
checkLoad(xidlt(1,8), nil, 0, ioerr) checkLoad(xidlt(1,8), nil, 0, ioerr)
...@@ -247,6 +251,7 @@ func TestCache(t *testing.T) { ...@@ -247,6 +251,7 @@ func TestCache(t *testing.T) {
rce1_b8 := oce1.rcev[2] rce1_b8 := oce1.rcev[2]
checkRCE(rce1_b8, 8, 0, nil, ioerr) checkRCE(rce1_b8, 8, 0, nil, ioerr)
checkOCE(1, rce1_b4, rce1_b7, rce1_b8) checkOCE(1, rce1_b4, rce1_b7, rce1_b8)
checkMRU(rce1_b8, rce1_b7, rce1_b4)
// load <10 -> ioerr + new rce (IO errors are not merged) // load <10 -> ioerr + new rce (IO errors are not merged)
checkLoad(xidlt(1,10), nil, 0, ioerr) checkLoad(xidlt(1,10), nil, 0, ioerr)
...@@ -254,6 +259,7 @@ func TestCache(t *testing.T) { ...@@ -254,6 +259,7 @@ func TestCache(t *testing.T) {
rce1_b10 := oce1.rcev[3] rce1_b10 := oce1.rcev[3]
checkRCE(rce1_b10, 10, 0, nil, ioerr) checkRCE(rce1_b10, 10, 0, nil, ioerr)
checkOCE(1, rce1_b4, rce1_b7, rce1_b8, rce1_b10) checkOCE(1, rce1_b4, rce1_b7, rce1_b8, rce1_b10)
checkMRU(rce1_b10, rce1_b8, rce1_b7, rce1_b4)
// load <11 -> new data rce, not merged with ioerr @<10 // load <11 -> new data rce, not merged with ioerr @<10
checkLoad(xidlt(1,11), world, 10, nil) checkLoad(xidlt(1,11), world, 10, nil)
...@@ -261,6 +267,7 @@ func TestCache(t *testing.T) { ...@@ -261,6 +267,7 @@ func TestCache(t *testing.T) {
rce1_b11 := oce1.rcev[4] rce1_b11 := oce1.rcev[4]
checkRCE(rce1_b11, 11, 10, world, nil) checkRCE(rce1_b11, 11, 10, world, nil)
checkOCE(1, rce1_b4, rce1_b7, rce1_b8, rce1_b10, rce1_b11) checkOCE(1, rce1_b4, rce1_b7, rce1_b8, rce1_b10, rce1_b11)
checkMRU(rce1_b11, rce1_b10, rce1_b8, rce1_b7, rce1_b4)
// load <12 -> <11 merged with <12 // load <12 -> <11 merged with <12
checkLoad(xidlt(1,12), world, 10, nil) checkLoad(xidlt(1,12), world, 10, nil)
...@@ -269,6 +276,7 @@ func TestCache(t *testing.T) { ...@@ -269,6 +276,7 @@ func TestCache(t *testing.T) {
ok1(rce1_b12 != rce1_b11) ok1(rce1_b12 != rce1_b11)
checkRCE(rce1_b12, 12, 10, world, nil) checkRCE(rce1_b12, 12, 10, world, nil)
checkOCE(1, rce1_b4, rce1_b7, rce1_b8, rce1_b10, rce1_b12) checkOCE(1, rce1_b4, rce1_b7, rce1_b8, rce1_b10, rce1_b12)
checkMRU(rce1_b12, rce1_b10, rce1_b8, rce1_b7, rce1_b4)
// simulate case where <14 and <16 were loaded in parallel, both are ready // simulate case where <14 and <16 were loaded in parallel, both are ready
// but <14 takes oce lock first before <16 and so <12 is not yet merged // but <14 takes oce lock first before <16 and so <12 is not yet merged
...@@ -281,17 +289,20 @@ func TestCache(t *testing.T) { ...@@ -281,17 +289,20 @@ func TestCache(t *testing.T) {
rce1_b16.data = world rce1_b16.data = world
checkOCE(1, rce1_b4, rce1_b7, rce1_b8, rce1_b10, rce1_b12, rce1_b16) checkOCE(1, rce1_b4, rce1_b7, rce1_b8, rce1_b10, rce1_b12, rce1_b16)
ok1(!rce1_b16.loaded()) ok1(!rce1_b16.loaded())
checkMRU(rce1_b12, rce1_b10, rce1_b8, rce1_b7, rce1_b4) // no <16 yet
// (lookup <14 while <16 is not yet loaded so <16 is not picked // (lookup <14 while <16 is not yet loaded so <16 is not picked
// automatically at lookup phase) // automatically at lookup phase)
rce1_b14, new14 := c.lookupRCE(xidlt(1,14)) rce1_b14, new14 := c.lookupRCE(xidlt(1,14))
ok1(new14) ok1(new14)
checkOCE(1, rce1_b4, rce1_b7, rce1_b8, rce1_b10, rce1_b12, rce1_b14, rce1_b16) checkOCE(1, rce1_b4, rce1_b7, rce1_b8, rce1_b10, rce1_b12, rce1_b14, rce1_b16)
checkMRU(rce1_b12, rce1_b10, rce1_b8, rce1_b7, rce1_b4) // no <14 and <16 yet
// (now <16 becomes ready but not yet takes oce lock) // (now <16 becomes ready but not yet takes oce lock)
close(rce1_b16.ready) close(rce1_b16.ready)
ok1(rce1_b16.loaded()) ok1(rce1_b16.loaded())
checkOCE(1, rce1_b4, rce1_b7, rce1_b8, rce1_b10, rce1_b12, rce1_b14, rce1_b16) checkOCE(1, rce1_b4, rce1_b7, rce1_b8, rce1_b10, rce1_b12, rce1_b14, rce1_b16)
checkMRU(rce1_b12, rce1_b10, rce1_b8, rce1_b7, rce1_b4) // no <14 and <16 yet
// (<14 also becomes ready and takes oce lock first, merging <12 and <14 into <16) // (<14 also becomes ready and takes oce lock first, merging <12 and <14 into <16)
c.loadRCE(rce1_b14, 1) c.loadRCE(rce1_b14, 1)
...@@ -299,6 +310,7 @@ func TestCache(t *testing.T) { ...@@ -299,6 +310,7 @@ func TestCache(t *testing.T) {
checkRCE(rce1_b16, 16, 10, world, nil) checkRCE(rce1_b16, 16, 10, world, nil)
checkRCE(rce1_b12, 12, 10, world, nil) checkRCE(rce1_b12, 12, 10, world, nil)
checkOCE(1, rce1_b4, rce1_b7, rce1_b8, rce1_b10, rce1_b16) checkOCE(1, rce1_b4, rce1_b7, rce1_b8, rce1_b10, rce1_b16)
checkMRU(rce1_b16, rce1_b10, rce1_b8, rce1_b7, rce1_b4)
// load =17 -> <16 merged with <18 // load =17 -> <16 merged with <18
checkLoad(xideq(1,17), nil, 0, &zodb.ErrXidMissing{xideq(1,17)}) checkLoad(xideq(1,17), nil, 0, &zodb.ErrXidMissing{xideq(1,17)})
...@@ -307,6 +319,7 @@ func TestCache(t *testing.T) { ...@@ -307,6 +319,7 @@ func TestCache(t *testing.T) {
ok1(rce1_b18 != rce1_b16) ok1(rce1_b18 != rce1_b16)
checkRCE(rce1_b18, 18, 10, world, nil) checkRCE(rce1_b18, 18, 10, world, nil)
checkOCE(1, rce1_b4, rce1_b7, rce1_b8, rce1_b10, rce1_b18) checkOCE(1, rce1_b4, rce1_b7, rce1_b8, rce1_b10, rce1_b18)
checkMRU(rce1_b18, rce1_b10, rce1_b8, rce1_b7, rce1_b4)
// load =18 -> new <19 // load =18 -> new <19
checkLoad(xideq(1,18), www, 18, nil) checkLoad(xideq(1,18), www, 18, nil)
...@@ -314,6 +327,7 @@ func TestCache(t *testing.T) { ...@@ -314,6 +327,7 @@ func TestCache(t *testing.T) {
rce1_b19 := oce1.rcev[5] rce1_b19 := oce1.rcev[5]
checkRCE(rce1_b19, 19, 18, www, nil) checkRCE(rce1_b19, 19, 18, www, nil)
checkOCE(1, rce1_b4, rce1_b7, rce1_b8, rce1_b10, rce1_b18, rce1_b19) checkOCE(1, rce1_b4, rce1_b7, rce1_b8, rce1_b10, rce1_b18, rce1_b19)
checkMRU(rce1_b19, rce1_b18, rce1_b10, rce1_b8, rce1_b7, rce1_b4)
// load =19 -> <19 merged with <20 // load =19 -> <19 merged with <20
checkLoad(xideq(1,19), nil, 0, &zodb.ErrXidMissing{xideq(1,19)}) checkLoad(xideq(1,19), nil, 0, &zodb.ErrXidMissing{xideq(1,19)})
...@@ -322,7 +336,7 @@ func TestCache(t *testing.T) { ...@@ -322,7 +336,7 @@ func TestCache(t *testing.T) {
ok1(rce1_b20 != rce1_b19) ok1(rce1_b20 != rce1_b19)
checkRCE(rce1_b20, 20, 18, www, nil) checkRCE(rce1_b20, 20, 18, www, nil)
checkOCE(1, rce1_b4, rce1_b7, rce1_b8, rce1_b10, rce1_b18, rce1_b20) checkOCE(1, rce1_b4, rce1_b7, rce1_b8, rce1_b10, rce1_b18, rce1_b20)
checkMRU(rce1_b20, rce1_b18, rce1_b10, rce1_b8, rce1_b7, rce1_b4)
// ---- verify rce lookup for must be cached entries ---- // ---- verify rce lookup for must be cached entries ----
...@@ -368,6 +382,7 @@ func TestCache(t *testing.T) { ...@@ -368,6 +382,7 @@ func TestCache(t *testing.T) {
c.loadRCE(rce1_b9, 1) c.loadRCE(rce1_b9, 1)
checkRCE(rce1_b9, 9, 0, nil, ioerr) checkRCE(rce1_b9, 9, 0, nil, ioerr)
checkOCE(1, rce1_b4, rce1_b7, rce1_b8, rce1_b9, rce1_b10, rce1_b18, rce1_b20) checkOCE(1, rce1_b4, rce1_b7, rce1_b8, rce1_b9, rce1_b10, rce1_b18, rce1_b20)
checkMRU(rce1_b9, rce1_b20, rce1_b18, rce1_b10, rce1_b8, rce1_b7, rce1_b4)
checkLookup(xideq(1,8), rce1_b9) checkLookup(xideq(1,8), rce1_b9)
checkLookup(xidlt(1,8), rce1_b8) checkLookup(xidlt(1,8), rce1_b8)
...@@ -390,6 +405,16 @@ func TestCache(t *testing.T) { ...@@ -390,6 +405,16 @@ func TestCache(t *testing.T) {
checkLookup(xideq(1,1), rce1_b4) checkLookup(xideq(1,1), rce1_b4)
checkLookup(xidlt(1,1), rce1_b4) checkLookup(xidlt(1,1), rce1_b4)
// ---- verify how LRU changes for in-cache loads ----
checkMRU(rce1_b9, rce1_b20, rce1_b18, rce1_b10, rce1_b8, rce1_b7, rce1_b4)
checkLoad(xidlt(1,7), hello, 4, nil)
checkMRU(rce1_b7, rce1_b9, rce1_b20, rce1_b18, rce1_b10, rce1_b8, rce1_b4)
checkLoad(xidlt(1,18), world, 10, nil)
checkMRU(rce1_b18, rce1_b7, rce1_b9, rce1_b20, rce1_b10, rce1_b8, rce1_b4)
// XXX verify LRU eviction // XXX verify LRU eviction
// XXX verify db inconsistency checks // XXX verify db inconsistency checks
// XXX verify loading with before > cache.before // XXX verify loading with before > cache.before
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment