/**
* Copyright 2012 Anjuke Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.anjuke.romar.mahout.persistence;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public abstract class AbstractFilePreferenceSource implements PreferenceSource {
private final File _path;
public static final String LOG_FILE_PREFIX = "romar.log.";
public static final String SNAPSHOT_FILE = "romar.snapshot.";
private long _version;
public AbstractFilePreferenceSource(File path) {
if (!path.exists()) {
if (!path.mkdirs()) {
throw new IllegalStateException("cannot mkdirs on _path "
+ path.getAbsolutePath());
}
} else if (!path.isDirectory()) {
throw new IllegalStateException(path.getAbsolutePath() + " must be directory");
}
_path = path;
verifyNewestVersion();
}
private synchronized void verifyNewestVersion() {
List<File> logFileList = listLogFileNamesAndSorted();
if (logFileList.isEmpty()) {
_version = -1;
} else {
_version = getInitFileVersion(logFileList.get(logFileList.size() - 1));
}
}
protected File getSnapshotFile(long version) {
File tmpFile = new File(_path, SNAPSHOT_FILE + version);
return tmpFile;
}
protected synchronized File getLatestLogFile() {
List<File> list = listLogFileNamesAndSorted();
if (list.isEmpty()) {
return createNewLogFile();
} else {
return list.get(list.size() - 1);
}
}
protected synchronized File createNewLogFile() {
_version++;
File file = new File(_path, LOG_FILE_PREFIX + _version);
try {
file.createNewFile();
} catch (IOException e) {
throw new RuntimeException(e);
}
return file;
}
protected synchronized File getLatestSnapshotFile() {
List<File> list = listSnapshotFileNamesAndSorted();
if (list.isEmpty()) {
return null;
} else {
return list.get(list.size() - 1);
}
}
protected synchronized long getCurrentVersion() {
return _version;
}
protected List<File> listSnapshotFileNamesAndSorted() {
File[] files = _path.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.startsWith(SNAPSHOT_FILE);
}
});
if (files == null || files.length == 0) {
return Collections.emptyList();
}
Arrays.sort(files, new Comparator<File>() {
@Override
public int compare(File f1, File f2) {
return Double.compare(getSnapshotFileVersion(f1),
getSnapshotFileVersion(f2));
}
});
return Arrays.asList(files);
}
protected List<File> listLogFileNamesAndSorted() {
File[] files = _path.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.startsWith(LOG_FILE_PREFIX);
}
});
if (files == null || files.length == 0) {
return Collections.emptyList();
}
Arrays.sort(files, new Comparator<File>() {
@Override
public int compare(File f1, File f2) {
return Double.compare(getLogFileVersion(f1), getLogFileVersion(f2));
}
});
return Arrays.asList(files);
}
private long getInitFileVersion(File file) {
long version = getLogFileVersion(file);
if (file.length() == 0) {
version = version - 1;
}
return version;
}
protected long getLogFileVersion(File file) {
String name = file.getName();
long version = Long.parseLong(name.substring(LOG_FILE_PREFIX.length()));
return version;
}
protected long getSnapshotFileVersion(File file) {
String name = file.getName();
return Long.parseLong(name.substring(SNAPSHOT_FILE.length()));
}
/**
* include version
*
* @param version
* @return
*/
protected List<File> getLogFileListUntilVersion(long version) {
if (version < 0) {
return Collections.emptyList();
}
List<File> list = listLogFileNamesAndSorted();
if (list.isEmpty()) {
return Collections.emptyList();
}
final List<File> logFileList = new ArrayList<File>(list.size() - 1);
for (File file : list) {
long fileVersion = getLogFileVersion(file);
if (fileVersion > version) {
break;
}
logFileList.add(file);
}
return logFileList;
}
protected List<File> getLogFileListFromVersion(long version) {
List<File> list = listLogFileNamesAndSorted();
final List<File> logFileList = new ArrayList<File>(list.size() - 1);
for (File file : list) {
long fileVersion = getLogFileVersion(file);
if (fileVersion <= version) {
continue;
}
if (fileVersion >= _version) {
break;
}
logFileList.add(file);
}
return logFileList;
}
}