/* * Copyright 2009 VoidSearch.com * * 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 com.voidsearch.voidbase.storage.bdb; import com.sleepycat.persist.StoreConfig; import com.sleepycat.persist.EntityStore; import com.sleepycat.persist.PrimaryIndex; import com.sleepycat.je.EnvironmentConfig; import com.sleepycat.je.Environment; import com.sleepycat.je.DatabaseException; import com.voidsearch.voidbase.storage.StorageException; import com.voidsearch.voidbase.util.GenericUtil; import java.io.File; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class BDBStore { protected Environment env = null; protected EntityStore store = null; protected StoreConfig storeConfig = new StoreConfig(); protected EnvironmentConfig envConfig = new EnvironmentConfig(); protected PrimaryIndex<String, BDBRecord> pIdx; protected static final Logger logger = LoggerFactory.getLogger(BDBStorage.class.getName()); public BDBStore(String name, String path) throws StorageException { Environment env; // create path recursively if it doesn't exist createPath(path); // open BDB store envConfig.setAllowCreate(true); envConfig.setSharedCache(true); storeConfig.setAllowCreate(true); try { env = new Environment(new File(path), envConfig); store = new EntityStore(env, name, storeConfig); pIdx = store.getPrimaryIndex(String.class, BDBRecord.class); } catch (DatabaseException e) { logger.error("Failed to open database " + name + " with path: " + path); GenericUtil.logException(e); throw new StorageException("Failed to open database " + name + " with path: " + path); } } public void close() throws StorageException { try { store.close(); env.close(); } catch (DatabaseException e) { logger.error("Failed to close database: " + e.getMessage()); GenericUtil.logException(e); throw new StorageException("Failed to close database"); } finally { store = null; env = null; } } public void put (String key, String value) throws StorageException { try { pIdx.put(new BDBRecord(key, value)); } catch (DatabaseException e) { logger.error("Failed to put " + key + " to database: " + e.getMessage()); GenericUtil.logException(e); throw new StorageException("Failed to put " + key + " to database: " + e.getMessage()); } } public String get(String key) throws StorageException { BDBRecord record; try { record = pIdx.get(key); } catch (DatabaseException e) { logger.error("Failed to get " + key + " from database: " + e.getMessage()); GenericUtil.logException(e); throw new StorageException("Failed to get " + key + " from database: " + e.getMessage()); } return record != null ? record.value : null; } public void delete(String key) throws StorageException { try { pIdx.delete(key); } catch (DatabaseException e) { logger.error("Failed to delete " + key + " from database: " + e.getMessage()); GenericUtil.logException(e); throw new StorageException("Failed to close database"); } } public synchronized void flush() throws StorageException { try { for (BDBRecord record: pIdx.entities()) { pIdx.delete(record.key); } } catch (DatabaseException e) { logger.error("Failed to flush database: " + e.getMessage()); GenericUtil.logException(e); throw new StorageException("Failed to flush database: " + e.getMessage()); } } protected void createPath(String path) throws StorageException { File dir = new File(path); // check if resource exists and is it a dir if (dir.exists()) { if (!dir.isDirectory()) { throw new StorageException("Path " + path + " exists but resource is not directory."); } } else if (!dir.mkdirs()) { throw new StorageException("Failed to create directory: " + path); } } }