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     */
017    package org.apache.activemq.kaha.impl.async;
018    
019    import java.io.File;
020    import java.io.IOException;
021    import java.io.RandomAccessFile;
022    
023    import org.apache.activemq.util.IOHelper;
024    import org.apache.activemq.util.LinkedNode;
025    
026    /**
027     * DataFile
028     * 
029     * 
030     */
031    public 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    }