/* DirPool.java * * Copyright (c) 2002, Benja Fallenstein * * This file is part of Storm. * * Storm is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Storm is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General * Public License for more details. * * You should have received a copy of the GNU Lesser General * Public License along with Storm; if not, write to the Free * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * * */ /* * Written by Benja Fallenstein */ package org.nongnu.storm.impl; import org.nongnu.storm.*; import org.nongnu.storm.headers.*; import java.io.*; import java.util.*; /** A StormPool storing blocks in individual files in a directory. * File names have the form b_idstring. */ public class DirPool extends AbstractLocalPool { /** The directory we store our blocks in. */ File dir; /** The DB objects by index type URI. */ protected Map dbs = new HashMap(); /** Get the File object for the block * corresponding to a given id. * This is needed in many places and wrapping it in a convenience * function makes code easier to read & maintain. */ protected final File getFile(BlockId id) { String hex = org.nongnu.storm.util.HexUtil.byteArrToHex(id.getBytes()); return new File(dir, "b_" + hex); } /** Read the header of the block * corresponding to the given id. * Like getFile(), this is needed in a number * of different places. */ protected final Header822 getFileHeader(BlockId id) throws IOException { InputStream is = new BufferedInputStream( id.getCheckedInputStream(new FileInputStream(getFile(id)))); Header822 header = Headers822.readHeader(is); is.close(); return header; } protected class FileBlockOutputStream extends AbstractBlockOutputStream { protected File tempFile; protected FileBlockOutputStream(Header822 header, File tempFile) throws IOException { super(new BufferedOutputStream(new FileOutputStream(tempFile)), header); this.tempFile = tempFile; } public Block makeBlock() throws IOException { BlockId id = makeIdFromDigest(); File file = getFile(id); if(!tempFile.renameTo(file)) { tempFile.delete(); throw new IOException("Could not rename temporary file"); } block = new FileBlock(id); added(block); return block; } } protected class FileBlock extends AbstractBlock { protected File file; protected FileBlock(BlockId id) throws IOException { super(id, getFileHeader(id)); this.file = getFile(id); } public InputStream getRawInputStream() throws IOException { return new BufferedInputStream( id.getCheckedInputStream(new FileInputStream(file))); } } /** Create a new DirPool. * @param dir The directory blocks are stored in. * Must already exist. * @throws IllegalArgumentException if the file isn't a directory * or does not exist yet. */ public DirPool(File dir, Set indexTypes) throws IOException { super(indexTypes); this.dir = dir; super.initializeIndices(); } protected void initializeIndices() throws IOException { } public Block get(BlockId id) throws IOException { return new FileBlock(id); } public void add(Block b) throws IOException { File temp = org.nongnu.storm.util.TempFileUtil.tmpFile(dir); BlockId id = b.getId(); InputStream is = id.getCheckedInputStream(b.getRawInputStream()); OutputStream os = new BufferedOutputStream(new FileOutputStream(temp)); org.nongnu.storm.util.CopyUtil.copy(is, os); if(!temp.renameTo(getFile(id))) throw new IOException("Could not rename temporary file"); added(get(id)); } public void delete(Block b) throws IOException { getFile(b.getId()).delete(); } public SetCollector getIds() { HashSet ids = new HashSet(); String[] list = dir.list(); for(int i=0; i