001/**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.activemq.kaha.impl.async;
018
019import java.io.File;
020import java.io.IOException;
021import java.io.RandomAccessFile;
022
023import org.apache.activemq.util.IOHelper;
024import org.apache.activemq.util.LinkedNode;
025
026/**
027 * DataFile
028 * 
029 * 
030 */
031public class DataFile extends LinkedNode implements Comparable<DataFile> {
032
033    protected final File file;
034    protected final Integer dataFileId;
035    protected final int preferedSize;
036
037    protected int length;
038    protected int referenceCount;
039
040    DataFile(File file, int number, int preferedSize) {
041        this.file = file;
042        this.preferedSize = preferedSize;
043        this.dataFileId = Integer.valueOf(number);
044        length = (int)(file.exists() ? file.length() : 0);
045    }
046    
047    File getFile() {
048        return file;
049    }
050
051    public Integer getDataFileId() {
052        return dataFileId;
053    }
054
055    public synchronized int getLength() {
056        return length;
057    }
058
059    public void setLength(int length) {
060        this.length = length;
061    }
062
063    public synchronized void incrementLength(int size) {
064        length += size;
065    }
066
067    public synchronized int increment() {
068        return ++referenceCount;
069    }
070
071    public synchronized int decrement() {
072        return --referenceCount;
073    }
074    
075    public synchronized int getReferenceCount(){
076        return referenceCount;
077    }
078
079    public synchronized boolean isUnused() {
080        return referenceCount <= 0;
081    }
082
083    public synchronized String toString() {
084        String result = file.getName() + " number = " + dataFileId + " , length = " + length + " refCount = " + referenceCount;
085        return result;
086    }
087
088    public synchronized RandomAccessFile openRandomAccessFile(boolean appender) throws IOException {
089        RandomAccessFile rc = new RandomAccessFile(file, "rw");
090        // When we start to write files size them up so that the OS has a chance
091        // to allocate the file contiguously.
092        if (appender) {
093            if (length < preferedSize) {
094                try {
095                    // this can throw if we run out of disk space
096                    rc.setLength(preferedSize);
097                } catch (IOException ioe) {            
098                    try {
099                        rc.close();
100                    } catch(Exception ignored) {
101                    }
102                    throw ioe;
103                }
104            }
105        }
106        return rc;
107    }
108
109    public synchronized void closeRandomAccessFile(RandomAccessFile file) throws IOException {
110        // On close set the file size to the real size.
111        if (length != file.length()) {
112            file.setLength(getLength());
113        }
114        file.close();
115    }
116
117    public synchronized boolean delete() throws IOException {
118        return file.delete();
119    }
120    
121    public synchronized void move(File targetDirectory) throws IOException{
122        IOHelper.moveFile(file,targetDirectory);
123    }
124
125    public int compareTo(DataFile df) {
126        return dataFileId - df.dataFileId;
127    }
128
129    @Override
130    public boolean equals(Object o) {
131        boolean result = false;
132        if (o instanceof DataFile) {
133            result = compareTo((DataFile)o) == 0;
134        }
135        return result;
136    }
137
138    @Override
139    public int hashCode() {
140        return dataFileId;
141    }
142}