Java tutorial
/* * 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); } }