/*
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