use of com.bonree.brfs.disknode.data.write.record.RecordElement in project BRFS by zhangnianli.
the class FileLengthMessageHandler method getRecordElements.
private List<RecordElement> getRecordElements(String filePath) {
List<RecordElement> recordInfo = null;
try {
Pair<RecordFileWriter, WriteWorker> binding = writerManager.getBinding(filePath, false);
if (binding != null) {
RecordElementReader recordReader = null;
try {
binding.first().flush();
writerManager.adjustFileWriter(filePath);
RecordCollection recordSet = binding.first().getRecordCollection();
recordReader = recordSet.getRecordElementReader();
recordInfo = new ArrayList<RecordElement>();
for (RecordElement element : recordReader) {
recordInfo.add(element);
}
} catch (Exception e) {
LOG.error("getSequnceNumbers from file[{}] error", filePath, e);
} finally {
CloseUtils.closeQuietly(recordReader);
}
} else {
// 到这有两种情况:
// 1、文件打开操作未成功后进行同步;
// 2、文件关闭操作未成功进行再次关闭;
recordInfo = new ArrayList<RecordElement>();
File dataFile = new File(filePath);
if (dataFile.exists()) {
// 到这的唯一机会是,多副本文件关闭时只有部分关闭成功,当磁盘节点恢复正常
// 后,需要再次进行同步流程让所有副本文件关闭,因为没有日志文件,所以只能
// 通过解析数据文件生成序列号列表
byte[] bytes = DataFileReader.readFile(dataFile);
List<String> offsetInfos = FileDecoder.getDataFileOffsets(fileFormater.fileHeader().length(), bytes);
for (String info : offsetInfos) {
List<String> parts = Splitter.on('|').splitToList(info);
int offset = Integer.parseInt(parts.get(0));
int size = Integer.parseInt(parts.get(1));
recordInfo.add(new RecordElement(offset, size, 0));
}
}
}
} catch (Exception e) {
LOG.error("get record element error", e);
}
return recordInfo;
}
use of com.bonree.brfs.disknode.data.write.record.RecordElement in project BRFS by zhangnianli.
the class FileWriterManager method adjustFileWriter.
public void adjustFileWriter(String filePath) throws IOException {
Pair<RecordFileWriter, WriteWorker> binding = runningWriters.get(filePath);
if (binding == null) {
throw new IllegalStateException("no writer of " + filePath + " is found for adjust");
}
List<RecordElement> originElements = binding.first().getRecordCollection().getRecordElementList();
LOG.info("adjust get [{}] records from record collection of [{}]", originElements.size(), filePath);
if (originElements.isEmpty()) {
// 没有数据写入成功,不需要任何协调
return;
}
List<RecordElement> elements = validElements(filePath, originElements);
LOG.info("adjust file get elements size[{}] for file[{}]", elements.size(), filePath);
RecordElement lastElement = elements.get(elements.size() - 1);
long validPosition = lastElement.getOffset() + lastElement.getSize();
LOG.debug("last element : {}", lastElement);
boolean needFlush = false;
if (validPosition != binding.first().position()) {
LOG.info("rewrite file content of file[{}] from[{}] to [{}]", filePath, binding.first().position(), validPosition);
// 数据文件的内容和日志信息不一致,需要调整数据文件
binding.first().position(validPosition);
needFlush = true;
}
if (elements.size() != originElements.size()) {
LOG.info("rewrite file records of file[{}]", filePath);
binding.first().getRecordCollection().clear();
for (RecordElement element : elements) {
binding.first().getRecordCollection().put(element);
}
needFlush = true;
}
if (needFlush) {
binding.first().flush();
}
}
Aggregations