-
Notifications
You must be signed in to change notification settings - Fork 2.3k
/
MuninnReadPageCursor.java
143 lines (127 loc) · 4.28 KB
/
MuninnReadPageCursor.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/*
* Copyright (c) 2002-2016 "Neo Technology,"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.neo4j.io.pagecache.impl.muninn;
import java.io.IOException;
import org.neo4j.io.pagecache.PageSwapper;
final class MuninnReadPageCursor extends MuninnPageCursor
{
protected long lockStamp;
@Override
protected void unpinCurrentPage()
{
MuninnPage p = page;
if ( p != null )
{
pinEvent.done();
}
lockStamp = 0; // make sure not to accidentally keep a lock state around
clearPageState();
}
@Override
public boolean next() throws IOException
{
unpinCurrentPage();
long lastPageId = assertPagedFileStillMappedAndGetIdOfLastPage();
if ( nextPageId > lastPageId )
{
return false;
}
pin( nextPageId, false );
currentPageId = nextPageId;
nextPageId++;
return true;
}
@Override
protected void lockPage( MuninnPage page )
{
lockStamp = page.tryOptimisticReadLock();
}
@Override
protected void unlockPage( MuninnPage page )
{
}
@Override
protected void pinCursorToPage( MuninnPage page, long filePageId, PageSwapper swapper )
{
reset( page );
page.incrementUsage();
}
@Override
protected void convertPageFaultLock( MuninnPage page )
{
lockStamp = page.unlockExclusive();
}
@Override
public boolean shouldRetry() throws IOException
{
boolean needsRetry = !page.validateReadLock( lockStamp );
if ( needsRetry )
{
setOffset( 0 );
lockStamp = page.tryOptimisticReadLock();
// The page might have been evicted while we held the optimistic
// read lock, so we need to check with page.pin that this is still
// the page we're actually interested in:
if ( !page.isBoundTo( pagedFile.swapper, currentPageId ) )
{
// This is no longer the page we're interested in, so we have
// to redo the pinning.
// This might in turn lead to a new optimistic lock on a
// different page if someone else has taken the page fault for
// us. If nobody has done that, we'll take the page fault
// ourselves, and in that case we'll end up with first an exclusive
// lock during the faulting, and then an optimistic read lock once the
// fault itself is over.
// First, forget about this page in case pin() throws and the cursor
// is closed; we don't want unpinCurrentPage() to try unlocking
// this page.
page = null;
// Then try pin again.
pin( currentPageId, false );
}
}
return needsRetry;
}
@Override
public void putByte( byte value )
{
throw new IllegalStateException( "Cannot write to read-locked page" );
}
@Override
public void putLong( long value )
{
throw new IllegalStateException( "Cannot write to read-locked page" );
}
@Override
public void putInt( int value )
{
throw new IllegalStateException( "Cannot write to read-locked page" );
}
@Override
public void putBytes( byte[] data, int arrayOffset, int length )
{
throw new IllegalStateException( "Cannot write to read-locked page" );
}
@Override
public void putShort( short value )
{
throw new IllegalStateException( "Cannot write to read-locked page" );
}
}