/* 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.riotfamily.cachius.persistence; import java.io.File; import java.io.IOException; public class RoundRobinDiskStore implements DiskStore { private File baseDir; private int depth; private int[] index; private int maxFilesPerDir = 500; public RoundRobinDiskStore(File baseDir, int depth) { setBaseDir(baseDir); setDepth(depth); } private void setBaseDir(File baseDir) { this.baseDir = new File(baseDir, "items"); delete(this.baseDir); this.baseDir.mkdirs(); } public File getBaseDir() { return baseDir; } private void setDepth(int depth) { this.depth = depth; this.index = new int[depth]; } private static void delete(File f) { if (f.isDirectory()) { File[] entries = f.listFiles(); for (int i = 0; i < entries.length; i++) { delete(entries[i]); } } f.delete(); } public void setMaxFilesPerDir(int maxFilesPerDir) { this.maxFilesPerDir = maxFilesPerDir; } public synchronized File getFile() throws IOException { File f = null; while (f == null) { f = createFile(); } return f; } private File createFile() throws IOException { File f = getFile(depth-1); index[depth-1]++; f.getParentFile().mkdirs(); if (f.createNewFile()) { return f; } return null; } private File getFile(int level) { if (level == 0) { return baseDir; } if (index[level] >= maxFilesPerDir) { index[level] = 0; if (level > 1) { index[level-1]++; } } return new File(getFile(level-1), String.format("%03d", index[level])); } }