com.taobao.common.store.journal.DataFile Maven / Gradle / Ivy
/*
* (C) 2007-2012 Alibaba Group Holding Limited.
*
* 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.
* Authors:
* dogun (yuexuqiang at gmail.com)
*/
package com.taobao.common.store.journal;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
/**
* ??????һ???????ļ?
*
* @author dogun (yuexuqiang at gmail.com)
*/
class DataFile {
private final File file;
private final AtomicInteger referenceCount = new AtomicInteger(0);
protected FileChannel fc;
private final int number;
private volatile long currentPos;
/**
* ???캯???????ָ?????ļ??????ҽ?ָ??ָ???ļ???β
*
* @param file
* @throws IOException
*/
DataFile(final File file, final int number) throws IOException {
this(file, number, false);
}
/**
* ???캯???????ָ?????ļ??????ҽ?ָ??ָ???ļ???β
*
* @param file
* @throws IOException
*/
DataFile(final File file, final int number, final boolean force) throws IOException {
this.file = file;
this.fc = new RandomAccessFile(file, force ? "rws" : "rw").getChannel();
// ָ???Ƶ????
this.fc.position(this.fc.size());
this.currentPos = this.fc.position();
this.number = number;
}
int getNumber() {
return this.number;
}
/**
* ????ļ??Ĵ?С
*
* @return ?ļ??Ĵ?С
* @throws IOException
*/
long getLength() throws IOException {
return this.currentPos;
}
long position() throws IOException {
return this.currentPos;
}
void forward(final long offset) {
this.currentPos += offset;
}
void sync(final Condition condition) throws Exception {
while (this.fc.position() < this.currentPos) {
condition.await(1, TimeUnit.SECONDS);
}
this.fc.force(true);
}
/**
* ??ȡ?ļ??????ʱ??
*
* @return
* @throws IOException
*/
long lastModified() throws IOException {
return this.file.lastModified();
}
/**
* ɾ???ļ?
*
* @return ?Ƿ?ɾ???ɹ?
* @throws IOException
*/
boolean delete() throws IOException {
this.close();
return this.file.delete();
}
/**
* ǿ?ƽ?????д??Ӳ??
*
* @throws IOException
*/
void force() throws IOException {
this.fc.force(true);
}
/**
* ?ر??ļ?
*
* @throws IOException
*/
void close() throws IOException {
this.fc.close();
}
/**
* ???ļ???ȡ???ݵ?bf??ֱ?????????߶????ļ???β??
* ?ļ???ָ???????ƶ?bf?Ĵ?С
*
* @param bf
* @throws IOException
*/
void read(final ByteBuffer bf) throws IOException {
while (bf.hasRemaining()) {
final int l = this.fc.read(bf);
if (l < 0) {
break;
}
}
}
/**
* ???ļ????ƶ?λ?ö?ȡ???ݵ?bf??ֱ?????????߶????ļ???β??
* ?ļ?ָ?벻???ƶ?
*
* @param bf
* @param offset
* @throws IOException
*/
void read(final ByteBuffer bf, final long offset) throws IOException {
int size = 0;
int l = 0;
while (bf.hasRemaining()) {
l = this.fc.read(bf, offset + size);
if (l < 0) {
// ???ݻ?δд?룬æ?ȴ?
if (offset < this.currentPos) {
continue;
}
else {
break;
}
}
size += l;
}
}
/**
* д??bf???ȵ????ݵ??ļ????ļ?ָ???????ƶ?
*
* @param bf
* @return д?????ļ?position
* @throws IOException
*/
long write(final ByteBuffer bf) throws IOException {
while (bf.hasRemaining()) {
final int l = this.fc.write(bf);
if (l < 0) {
break;
}
}
return this.fc.position();
}
/**
* ??ָ??λ??д??bf???ȵ????ݵ??ļ????ļ?ָ??????????ƶ?
*
* @param offset
* @param bf
* @throws IOException
*/
void write(final long offset, final ByteBuffer bf) throws IOException {
int size = 0;
while (bf.hasRemaining()) {
final int l = this.fc.write(bf, offset + size);
size += l;
if (l < 0) {
break;
}
}
}
/**
* ???ļ?????һ?????ü???
*
* @return ???Ӻ?????ü???
*/
int increment() {
return this.referenceCount.incrementAndGet();
}
int increment(final int n) {
return this.referenceCount.addAndGet(n);
}
/**
* ???ļ?????һ?????ü???
*
* @return ???ٺ?????ü???
*/
int decrement() {
return this.referenceCount.decrementAndGet();
}
int decrement(final int n) {
return this.referenceCount.addAndGet(-n);
}
/**
* ?ļ??Ƿ???ʹ?ã????ü????Ƿ???0?ˣ?
*
* @return ?ļ??Ƿ???ʹ??
*/
boolean isUnUsed() {
return this.getReferenceCount() <= 0;
}
/**
* ??????ü?????ֵ
*
* @return ???ü?????ֵ
*/
int getReferenceCount() {
return this.referenceCount.get();
}
@Override
public String toString() {
String result = null;
try {
result =
this.file.getName() + " , length = " + this.getLength() + " refCount = " + this.referenceCount
+ " position:" + this.fc.position();
}
catch (final IOException e) {
result = e.getMessage();
}
return result;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy