-
Notifications
You must be signed in to change notification settings - Fork 2.3k
/
PagedFile.java
170 lines (163 loc) · 6.39 KB
/
PagedFile.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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/*
* 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;
import java.io.IOException;
/**
* The representation of a file that has been mapped into the associated page
* cache.
*/
public interface PagedFile extends AutoCloseable
{
/**
* Pin the pages with a shared lock.
*
* This implies {@link org.neo4j.io.pagecache.PagedFile#PF_NO_GROW}, since
* pages under shared locks cannot be safely written to anyway, so there's
* no point in trying to go beyond the end of the file.
*
* This cannot be combined with PF_EXCLUSIVE_LOCK.
*/
int PF_SHARED_LOCK = 1; // TODO rename PF_SHARED_READ_LOCK
/**
* Pin the pages with an exclusive lock.
*
* This will mark the pages as dirty, and caused them to be flushed, if
* they are evicted.
*
* This cannot be combined with PF_SHARED_LOCK.
*/
int PF_EXCLUSIVE_LOCK = 1 << 1; // TODO rename to PF_SHARED_WRITE_LOCK
/**
* Disallow pinning and navigating to pages outside the range of the
* underlying file.
*/
int PF_NO_GROW = 1 << 2;
/**
* Read-ahead hint for sequential forward scanning.
*/
int PF_READ_AHEAD = 1 << 3; // TBD
/**
* Do not load in the page if it is not loaded already. Only useful with
* exclusive locking when you want to overwrite the whole page anyway.
*/
int PF_NO_FAULT = 1 << 4; // TBD
/**
* Do not update page access statistics.
*/
int PF_TRANSIENT = 1 << 5; // TBD
/**
* Initiate an IO interaction with the contents of the paged file.
*
* <p>The basic structure of an interaction looks like this:
*
* <pre><code>
* try ( PageCursor cursor = pagedFile.io( startingPageId, intentFlags ) )
* {
* if ( cursor.next() )
* {
* do
* {
* // perform read or write operations on the page
* }
* while ( cursor.shouldRetry() );
* }
* }
* </code></pre>
*
* {@link org.neo4j.io.pagecache.PageCursor PageCursors} are
* <code>AutoCloseable</code>, so interacting with them using
* <code>try-with-resources</code> is recommended.
*
* <p>The returned PageCursor is initially not bound, so
* {@link PageCursor#next() next} must be called on it before it can be
* used.
*
* <p>The first <code>next</code> call will advance the cursor to the
* initial page, as given by the <code>pageId</code> parameter.
* Until then, the cursor won't be bound to any page, the
* {@link PageCursor#getCurrentPageId()} method will return the
* {@link org.neo4j.io.pagecache.PageCursor#UNBOUND_PAGE_ID} constant, and
* attempts at reading from or writing to the cursor will throw a
* NullPointerException.
*
* <p>After the <code>next</code> call, if it returns <code>true</code>,
* the cursor will be bound to a page, and the get and put methods will
* access that page.
*
* <p>After a call to {@link PageCursor#rewind()}, the cursor will return
* to its initial state.
*
* <p>The <code>pf_flags</code> argument expresses the intent of the IO
* operation.
* It is a bitmap that combines various <code>PF_*</code> constants.
* You must always specify your desired locking behaviour, with either
* {@link org.neo4j.io.pagecache.PagedFile#PF_EXCLUSIVE_LOCK} or
* {@link org.neo4j.io.pagecache.PagedFile#PF_SHARED_LOCK}.
* The two locking modes cannot be combined, but other intents can be
* combined with them.
* For instance, if you want to write to a page, but also make sure that
* you don't write beyond the end of the file, then you can express your
* intent with <code>PF_EXCLUSIVE_LOCK | PF_NO_GROW</code> – note how the
* flags are combined with a bitwise-OR operator.
*
*
*
* @param pageId The initial file-page-id, that the cursor will be bound to
* after the first call to <code>next</code>.
* @param pf_flags A bitmap of <code>PF_*</code> constants composed with
* the bitwise-OR operator, that expresses the desired
* locking behaviour, and other hints.
* @return A PageCursor in its initial unbound state.
* Never <code>null</code>.
* @throws IOException if there was an error accessing the underlying file.
*/
PageCursor io( long pageId, int pf_flags ) throws IOException;
/**
* Get the size of the file-pages, in bytes.
*/
int pageSize();
/**
* Flush all dirty pages into the file channel, and force the file channel to disk.
*
* Note: Flushing has to take locks on pages, so you cannot call flush
* while you have pages pinned.
*/
void flushAndForce() throws IOException;
/**
* Get the file-page-id of the last page in the file.
*
* This will return <em>a negative number</em> (not necessarily -1) if the file is completely empty.
*
* @throws IllegalStateException if this file has been unmapped
*/
long getLastPageId() throws IOException;
/**
* Release a handle to a paged file.
*
* If this is the last handle to the file, it will be flushed and closed.
*
* Note that this operation assumes that there are no write page cursors open on the paged file. If there are, then
* their writes may be lost, as they might miss the last flush that can happen on their data.
*
* @see AutoCloseable#close()
* @throws IOException instead of the Exception superclass as defined in AutoCloseable, if .
*/
void close() throws IOException;
}