org.stem.db.FatFileAllocator.java Source code

Java tutorial

Introduction

Here is the source code for org.stem.db.FatFileAllocator.java

Source

/*
 * Copyright 2014 Alexey Plotnik
 *
 * 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 org.stem.db;

import com.google.common.io.Closer;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.stem.utils.BBUtils;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;

public class FatFileAllocator {

    private static final Logger logger = LoggerFactory.getLogger(MountPoint.class);

    private static final String FAT_FILE_NAME_TEMPLATE = "stem-ff-%06d.db";
    public static final String FAT_FILE_NAME_REGEX = "stem-ff-([0-9]{6}).db";

    public static void allocateFile(String filePath, long sizeInMB) throws IOException {
        allocateFile(filePath, sizeInMB, false);
    }

    public static FatFile create(String filePath, long sizeInMB) throws IOException {
        allocateFile(filePath, sizeInMB, true);
        return FatFile.open(filePath, new DataTracker(StorageNodeDescriptor.cluster().getVBucketsNum()));
    }

    public static void allocateFile(String filePath, long sizeInMB, boolean mark) throws IOException {
        long started = System.currentTimeMillis();

        Closer closer = Closer.create();
        try {
            File file = new File(filePath);
            if (file.exists())
                throw new IOException(String.format("File already exists: %s", filePath));

            RandomAccessFile rw = closer.register(new RandomAccessFile(file, "rw"));
            rw.setLength(sizeInMB * 1024 * 1024);
            if (mark) {
                rw.seek(0);
                rw.writeByte(FatFile.MARKER_BLANK);
                rw.seek(rw.length() - 1);
                rw.writeByte(FatFile.MARKER_BLANK);
            }
        } catch (Throwable e) {
            throw closer.rethrow(e);
        } finally {
            closer.close();
            logger.debug("{} was allocated in {} ms", filePath, System.currentTimeMillis() - started);
        }
    }

    public static void allocateDirectory(String directoryPath, long sizeInMB, long maxSize, boolean mark)
            throws IOException {
        long started = System.currentTimeMillis();
        File dir = BBUtils.getDirectory(directoryPath);
        // TODO: empty check

        long allocated = sizeInMB * 1024 * 1024;
        int fatFileIndex = 0;

        //while (FileSystemUtils.freeSpaceKb(directoryPath)/1024 > sizeInMB)
        while (maxSize >= allocated) {
            String fatFilePath = dir.getAbsolutePath() + File.separator + buildFileName(fatFileIndex);
            allocateFile(fatFilePath, sizeInMB, mark);
            allocated += sizeInMB * 1024 * 1024;
            fatFileIndex++;
        }
        int totalAllocated = fatFileIndex;
        if (0 == totalAllocated)
            throw new RuntimeException(
                    "Can't preallocate, maybe there is no free space on the device " + directoryPath);

        logger.debug("Directory {} ({}, {} files) was allocated in {} ms", directoryPath,
                FileUtils.byteCountToDisplaySize(maxSize), fatFileIndex, System.currentTimeMillis() - started);

    }

    /**
     * Allocate a directory with files of a given size
     *
     * @param directoryPath
     * @param sizeInMB
     * @throws IOException
     */
    public static void allocateDirectory(String directoryPath, long sizeInMB) throws IOException {
        File dir = BBUtils.getDirectory(directoryPath);
        allocateDirectory(directoryPath, sizeInMB, dir.getFreeSpace(), false);
    }

    public static String buildFileName(int fatFileIndex) {
        return String.format(FAT_FILE_NAME_TEMPLATE, fatFileIndex);
    }

}