-
Notifications
You must be signed in to change notification settings - Fork 2.3k
/
PhysicalLogFiles.java
137 lines (118 loc) · 4.42 KB
/
PhysicalLogFiles.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
/*
* 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.kernel.impl.transaction.log;
import java.io.File;
import java.io.IOException;
import java.util.regex.Pattern;
import org.neo4j.io.fs.FileSystemAbstraction;
import org.neo4j.kernel.impl.transaction.log.entry.LogHeader;
import static java.lang.Math.max;
import static java.lang.Math.min;
import static org.neo4j.kernel.impl.transaction.log.PhysicalLogFile.DEFAULT_VERSION_SUFFIX;
import static org.neo4j.kernel.impl.transaction.log.PhysicalLogFile.REGEX_DEFAULT_VERSION_SUFFIX;
import static org.neo4j.kernel.impl.transaction.log.entry.LogHeader.LOG_HEADER_SIZE;
import static org.neo4j.kernel.impl.transaction.log.entry.LogHeaderReader.readLogHeader;
/**
* Used to figure out what logical log file to open when the database
* starts up.
*/
public class PhysicalLogFiles
{
public interface LogVersionVisitor
{
void visit( File file, long logVersion );
}
private static class RangeLogVersionVisitor implements LogVersionVisitor
{
private long lowest = -1;
private long highest = -1;
@Override
public void visit( File file, long logVersion )
{
highest = max( highest, logVersion );
lowest = lowest == -1 ? logVersion : min( lowest, logVersion );
}
}
private final File logBaseName;
private final Pattern logFilePattern;
private final FileSystemAbstraction fileSystem;
public PhysicalLogFiles( File directory, String name, FileSystemAbstraction fileSystem )
{
this.logBaseName = new File( directory, name );
this.logFilePattern = Pattern.compile( name + REGEX_DEFAULT_VERSION_SUFFIX + "\\d+" );
this.fileSystem = fileSystem;
}
public PhysicalLogFiles( File directory, FileSystemAbstraction fileSystem )
{
this( directory, PhysicalLogFile.DEFAULT_NAME, fileSystem );
}
public File getLogFileForVersion( long version )
{
return new File( logBaseName.getPath() + DEFAULT_VERSION_SUFFIX + version );
}
public boolean versionExists( long version )
{
return fileSystem.fileExists( getLogFileForVersion( version ) );
}
public LogHeader extractHeader( long version ) throws IOException
{
return readLogHeader( fileSystem, getLogFileForVersion( version ) );
}
public boolean hasAnyEntries( long version )
{
return fileSystem.getFileSize( getLogFileForVersion( version ) ) > LOG_HEADER_SIZE;
}
public long getHighestLogVersion()
{
RangeLogVersionVisitor visitor = new RangeLogVersionVisitor();
accept( visitor );
return visitor.highest;
}
public long getLowestLogVersion()
{
RangeLogVersionVisitor visitor = new RangeLogVersionVisitor();
accept( visitor );
return visitor.lowest;
}
public void accept( LogVersionVisitor visitor )
{
for ( File file : fileSystem.listFiles( logBaseName.getParentFile() ) )
{
if ( logFilePattern.matcher( file.getName() ).matches() )
{
visitor.visit( file, getLogVersion( file ) );
}
}
}
public static long getLogVersion( File historyLogFile )
{
// Get version based on the name
return getLogVersion( historyLogFile.getName() );
}
public static long getLogVersion( String historyLogFilename )
{
int index = historyLogFilename.lastIndexOf( DEFAULT_VERSION_SUFFIX );
if ( index == -1 )
{
throw new RuntimeException( "Invalid log file '" + historyLogFilename + "'" );
}
return Long.parseLong( historyLogFilename.substring( index + DEFAULT_VERSION_SUFFIX.length() ) );
}
}