[Joafip-svn] SF.net SVN: joafip:[3003] trunk/joafip-babudb
Brought to you by:
luc_peuvrier
|
From: <luc...@us...> - 2012-04-10 03:40:28
|
Revision: 3003
http://joafip.svn.sourceforge.net/joafip/?rev=3003&view=rev
Author: luc_peuvrier
Date: 2012-04-10 03:40:22 +0000 (Tue, 10 Apr 2012)
Log Message:
-----------
data manager using babudb library
Added Paths:
-----------
trunk/joafip-babudb/pom.xml
trunk/joafip-babudb/src/
trunk/joafip-babudb/src/main/
trunk/joafip-babudb/src/main/java/
trunk/joafip-babudb/src/main/java/net/
trunk/joafip-babudb/src/main/java/net/sf/
trunk/joafip-babudb/src/main/java/net/sf/joafip/
trunk/joafip-babudb/src/main/java/net/sf/joafip/babudb/
trunk/joafip-babudb/src/main/java/net/sf/joafip/babudb/entity/
trunk/joafip-babudb/src/main/java/net/sf/joafip/babudb/service/
trunk/joafip-babudb/src/main/java/net/sf/joafip/babudb/service/BabudbDataManager.java
trunk/joafip-babudb/src/main/resources/
trunk/joafip-babudb/src/test/
trunk/joafip-babudb/src/test/java/
trunk/joafip-babudb/src/test/resources/
Property Changed:
----------------
trunk/joafip-babudb/
Property changes on: trunk/joafip-babudb
___________________________________________________________________
Added: svn:ignore
+ .settings
.classpath
.project
Added: trunk/joafip-babudb/pom.xml
===================================================================
--- trunk/joafip-babudb/pom.xml (rev 0)
+++ trunk/joafip-babudb/pom.xml 2012-04-10 03:40:22 UTC (rev 3003)
@@ -0,0 +1,57 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>net.sf.joafip</groupId>
+ <artifactId>joafip-parent</artifactId>
+ <version>1.0.0</version>
+ <relativePath>../joafip-parent</relativePath>
+ </parent>
+ <!-- <groupId>net.sf.joafip</groupId> -->
+ <artifactId>joafip-babudb</artifactId>
+ <packaging>jar</packaging>
+ <version>4.0.0b8</version>
+ <url>http://joafip.sourceforge.net/</url>
+ <name>Joafip storage using babudb</name>
+
+ <!-- <sourceDirectory>src_maven/main/java</sourceDirectory> <testSourceDirectory>src_maven/test/java</testSourceDirectory>
+ <resources><resource><directory>src_maven/main/resource</directory></resource></resources> -->
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.xtreemfs</groupId>
+ <artifactId>babudb</artifactId>
+ <version>0.5.6</version>
+ </dependency>
+
+ <dependency>
+ <groupId>net.sf.joafip</groupId>
+ <artifactId>joafip-common</artifactId>
+ <version>4.0.0b8</version>
+ </dependency>
+
+ <dependency>
+ <groupId>net.sf.joafip</groupId>
+ <artifactId>joafip-common</artifactId>
+ <version>4.0.0b8</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>net.sf.joafip</groupId>
+ <artifactId>joafip-kvstore</artifactId>
+ <version>4.0.0b8</version>
+ </dependency>
+
+ <dependency>
+ <groupId>net.sf.joafip</groupId>
+ <artifactId>joafip-log4j</artifactId>
+ <version>4.0.0b8</version>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+
+</project>
Added: trunk/joafip-babudb/src/main/java/net/sf/joafip/babudb/service/BabudbDataManager.java
===================================================================
--- trunk/joafip-babudb/src/main/java/net/sf/joafip/babudb/service/BabudbDataManager.java (rev 0)
+++ trunk/joafip-babudb/src/main/java/net/sf/joafip/babudb/service/BabudbDataManager.java 2012-04-10 03:40:22 UTC (rev 3003)
@@ -0,0 +1,454 @@
+/*
+ * Copyright 2012 Luc Peuvrier
+ * All rights reserved.
+ *
+ * This file is a part of JOAFIP.
+ *
+ * JOAFIP is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License.
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE
+ * Licensed under the LGPL License, Version 3, 29 June 2007 (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.gnu.org/licenses/lgpl.html
+ *
+ * JOAFIP is distributed in the hope that it will be useful, but
+ * 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 net.sf.joafip.babudb.service;
+
+import java.io.File;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
+import net.sf.joafip.kvstore.record.entity.DataRecordIdentifier;
+import net.sf.joafip.kvstore.record.service.IDataRecordKeyManager;
+import net.sf.joafip.kvstore.service.AbstractHeapDataManager;
+import net.sf.joafip.kvstore.service.HeapException;
+import net.sf.joafip.logger.JoafipLogger;
+
+import org.xtreemfs.babudb.BabuDBFactory;
+import org.xtreemfs.babudb.api.BabuDB;
+import org.xtreemfs.babudb.api.DatabaseManager;
+import org.xtreemfs.babudb.api.database.Database;
+import org.xtreemfs.babudb.api.exception.BabuDBException;
+import org.xtreemfs.babudb.config.ConfigBuilder;
+
+/**
+ *
+ * @author luc peuvrier
+ *
+ */
+public class BabudbDataManager extends AbstractHeapDataManager {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -9002962642414173846L;
+
+ /** single key on index #0 to store next data record identifier value */
+ private static final byte[] NEXT_ID = "nextId".getBytes();
+
+ /** message */
+ private static final String UNSUPPORTED = "unsupported";
+
+ /** message */
+ private static final String UNKNOWN_NEXT_IDENTIFIER = "unknown next identifier";
+
+ /** logger */
+ private final static JoafipLogger LOGGER = JoafipLogger
+ .getLogger(BabudbDataManager.class);
+
+ /** the database name */
+ private static final String DATA_BASE = "dataBase";
+
+ /** pending modification map */
+ private final Map<Long, byte[]> dataMap = new TreeMap<Long, byte[]>();
+
+ /** storage path */
+ private final String storageFileName;
+
+ private BabuDB databaseSystem;
+
+ private Database database;
+
+ /** next data record identifier value */
+ private long nextIdentifier;
+
+ public BabudbDataManager(final String storageFileName) {
+ super();
+ this.storageFileName = storageFileName;
+ }
+
+ @Override
+ protected void removeFiles() throws HeapException {
+ remove(new File(storageFileName));
+ }
+
+ private void remove(final File file) throws HeapException {
+ if (file.exists()) {
+ if (file.isDirectory()) {
+ for (File subFile : file.listFiles()) {
+ remove(subFile);
+ }
+ } else {
+ if (!file.delete()) {
+ throw new HeapException("failed delete file " + file);
+ }
+ }
+ }
+ }
+
+ @Override
+ protected void startServiceImpl(boolean removeFiles) throws HeapException {
+ try {
+ if (removeFiles) {
+ removeFiles();
+ }
+ ConfigBuilder configBuilder = new ConfigBuilder();
+ configBuilder.setDataPath(storageFileName);
+ databaseSystem = BabuDBFactory.createBabuDB(configBuilder.build());
+ DatabaseManager databaseManager = databaseSystem
+ .getDatabaseManager();
+ if (removeFiles || databaseManager.getDatabases().isEmpty()) {
+ /*
+ * case of remove existing data or database is empty
+ */
+ databaseManager.createDatabase(DATA_BASE, 2/* 2 index */);
+ database = databaseManager.getDatabase(DATA_BASE);
+ // initial value of next data record identifier
+ database.singleInsert(0, NEXT_ID, longToBytes(0), null);
+ nextIdentifier = 0;
+ } else {
+ /*
+ * to works with existing data base
+ */
+ database = databaseManager.getDatabase(DATA_BASE);
+ readNextIdentifier();
+ }
+ } catch (Exception exception) {
+ throw new HeapException(exception);
+ }
+ }
+
+ /**
+ * set {@link #nextIdentifier} from current value in database
+ *
+ * @throws BabuDBException
+ * @throws HeapException
+ */
+ private void readNextIdentifier() throws BabuDBException, HeapException {
+ byte[] bytes = database.lookup(0, NEXT_ID, null).get();
+ if (bytes == null) {
+ throw new HeapException(UNKNOWN_NEXT_IDENTIFIER);
+ }
+ nextIdentifier = bytesToLong(bytes);
+ }
+
+ @Override
+ protected void stopServiceImpl() throws HeapException {
+ try {
+ /*
+ * discard changes, not saved in database
+ */
+ dataMap.clear();
+ // create a checkpoint for faster start-ups
+ databaseSystem.getCheckpointer().checkpoint();
+ databaseSystem.shutdown();
+ } catch (Exception exception) {
+ throw new HeapException(exception);
+ }
+ }
+
+ @Override
+ protected void closeHeapManagerAfterException() {
+ // close all after error
+ try {
+ databaseSystem.shutdown();
+ } catch (Exception exception) {
+ // ignore error, only a log for information
+ LOGGER.error("closing after error", exception);
+ }
+ }
+
+ @Override
+ public boolean isDataLost() {
+ // can not check if data lost, assume database is consistent
+ return false;
+ }
+
+ @Override
+ public String getStorageFileName() throws HeapException {
+ return storageFileName;
+ }
+
+ @Override
+ public String getBackupFileName() throws HeapException {
+ throw new HeapException(UNSUPPORTED);
+ }
+
+ @Override
+ public String getChangeFileName() throws HeapException {
+ throw new HeapException(UNSUPPORTED);
+ }
+
+ @Override
+ protected void clearImpl() throws HeapException {
+ throw new HeapException(UNSUPPORTED);
+ }
+
+ @Override
+ protected void flushImp() throws HeapException {
+ try {
+ /*
+ * all changes in dataMap are inserted in database
+ */
+ // DatabaseInsertGroup group = database.createInsertGroup();
+ for (Map.Entry<Long, byte[]> entry : dataMap.entrySet()) {
+ // group.addInsert(1, longToBytes(entry.getKey()),
+ // entry.getValue());
+ database.singleInsert(1, longToBytes(entry.getKey()),
+ entry.getValue(), null);
+ }
+ dataMap.clear();
+ /*
+ * update next data record identifier in database
+ */
+ // group.addInsert(0, NEXT_ID, longToBytes(nextIdentifier));
+ database.singleInsert(0, NEXT_ID, longToBytes(nextIdentifier), null);
+ // database.insert(group, null).get();
+ } catch (Exception exception) {
+ throw new HeapException(exception);
+ }
+ }
+
+ @Override
+ protected void clearStandbyModificationImpl() throws HeapException {
+ try {
+ /*
+ * discard all changes
+ */
+ dataMap.clear();
+ readNextIdentifier();
+ } catch (Exception exception) {
+ throw new HeapException(exception);
+ }
+ }
+
+ @Override
+ protected DataRecordIdentifier getNextFreeDataRecordIdentifierImpl()
+ throws HeapException {
+ return new DataRecordIdentifier(nextIdentifier);
+ }
+
+ @Override
+ protected void setNextFreeDataRecordIdentifierImpl(
+ final DataRecordIdentifier dataRecordIdentifier)
+ throws HeapException {
+ nextIdentifier = dataRecordIdentifier.value;
+ }
+
+ @Override
+ protected DataRecordIdentifier getNewDataRecordIdentifierImpl()
+ throws HeapException {
+ return new DataRecordIdentifier(nextIdentifier++);
+ }
+
+ @Override
+ protected boolean deleteDataRecordImpl(
+ final DataRecordIdentifier dataRecordIdentifier)
+ throws HeapException {
+ try {
+ // deleted if exist in database or in pending modification map
+ boolean deleted;
+ byte[] bytes = database.lookup(1,
+ longToBytes(dataRecordIdentifier.value), null).get();
+ deleted = bytes != null;
+ deleted |= dataMap.put(dataRecordIdentifier.value, null) != null;
+ return deleted;
+ } catch (Exception exception) {
+ throw new HeapException(exception);
+ }
+ }
+
+ @Override
+ protected byte[] readDataRecordImpl(
+ final DataRecordIdentifier dataRecordIdentifier)
+ throws HeapException {
+ try {
+ /*
+ * first search in pending modification map, and then if not in
+ * pending modification map search in database
+ */
+ byte[] data = dataMap.get(dataRecordIdentifier.value);
+ if (data == null) {
+ data = database.lookup(1,
+ longToBytes(dataRecordIdentifier.value), null).get();
+ }
+ return data;
+ } catch (Exception exception) {
+ throw new HeapException(exception);
+ }
+ }
+
+ @Override
+ protected boolean writeDataRecordImpl(
+ final DataRecordIdentifier dataRecordIdentifier, byte[] data)
+ throws HeapException {
+ try {
+ // created if not exist in database nor in pending modification map
+ boolean created = !dataMap.containsKey(dataRecordIdentifier.value)
+ && database.lookup(1,
+ longToBytes(dataRecordIdentifier.value), null)
+ .get() != null;
+ // add to pending modification map
+ dataMap.put(dataRecordIdentifier.value, data);
+ return created;
+ } catch (Exception exception) {
+ throw new HeapException(exception);
+ }
+ }
+
+ @Override
+ protected boolean hasDataRecordImpl(
+ final DataRecordIdentifier dataRecordIdentifier)
+ throws HeapException {
+ try {
+ /*
+ * first search in pending modification map, and then if not in
+ * pending modification map search in database
+ */
+ return dataMap.containsKey(dataRecordIdentifier.value)
+ || database.lookup(1,
+ longToBytes(dataRecordIdentifier.value), null)
+ .get() != null;
+ } catch (Exception exception) {
+ throw new HeapException(exception);
+ }
+ }
+
+ @Override
+ protected int getNumberOfDataRecordImpl() throws HeapException {
+ // TODO how to count number of indexes #1 in database ?
+ return 0;
+ }
+
+ @Override
+ protected int getNumberOfFreeRecordImpl() throws HeapException {
+ // TODO no free records with babudb ?
+ return 0;
+ }
+
+ @Override
+ protected long heapSizeImpl() throws HeapException {
+ // TODO all babudb files used size sum ?
+ return 0;
+ }
+
+ @Override
+ protected long freeSizeImpl() throws HeapException {
+ // TODO is there free area in files used by babudb ?
+ return 0;
+ }
+
+ @Override
+ protected long usedSizeImpl() throws HeapException {
+ // TODO see free size
+ return 0;
+ }
+
+ @Override
+ protected DataRecordIdentifier removeFirstDataRecordImpl()
+ throws HeapException {
+ // not needed for basic usage
+ throw new HeapException(UNSUPPORTED);
+ }
+
+ @Override
+ protected Set<DataRecordIdentifier> getDataRecordIdentifierSetImpl()
+ throws HeapException {
+ // not needed for basic usage
+ throw new HeapException(UNSUPPORTED);
+ }
+
+ @Override
+ protected Iterator<DataRecordIdentifier> dataRecordIteratorImpl()
+ throws HeapException {
+ // not needed for basic usage
+ throw new HeapException(UNSUPPORTED);
+ }
+
+ @Override
+ public void backup(long identifier, int maxBackup) throws HeapException {
+ // not needed for basic usage
+ throw new HeapException(UNSUPPORTED);
+ }
+
+ @Override
+ public long getRecordPositionInfile(DataRecordIdentifier identifier)
+ throws HeapException {
+ // no meaning with babudb
+ throw new HeapException(UNSUPPORTED);
+ }
+
+ @Override
+ public long getLastRecordPositionInFile() throws HeapException {
+ // no meaning with babudb
+ throw new HeapException(UNSUPPORTED);
+ }
+
+ @Override
+ public void setDataRecordKeyComparator(
+ IDataRecordKeyManager dataRecordKeyComparator) throws HeapException {
+ // only data record identifier value used as key
+ throw new HeapException(UNSUPPORTED);
+ }
+
+ /**
+ * Unmarshal bytes to long value
+ *
+ * @param bytes
+ * the serialized form
+ * @return the long value
+ */
+ private long bytesToLong(final byte[] bytes) {
+ long longValue = 0;
+ longValue |= ((((long) bytes[0]) & 0xff) << 56);
+ longValue |= ((((long) bytes[1]) & 0xff) << 48);
+ longValue |= ((((long) bytes[2]) & 0xff) << 40);
+ longValue |= ((((long) bytes[3]) & 0xff) << 32);
+ longValue |= ((((long) bytes[4]) & 0xff) << 24);
+ longValue |= ((((long) bytes[5]) & 0xff) << 16);
+ longValue |= ((((long) bytes[6]) & 0xff) << 8);
+ longValue |= (((long) bytes[7]) & 0xff) & 0xff;
+ return longValue;
+ }
+
+ /**
+ * marshal a long value to bytes
+ *
+ * @param value
+ * the value
+ * @return the serialized form
+ */
+ private byte[] longToBytes(final long value) {
+ final byte[] binary = new byte[8];
+ binary[0] = (byte) (value >> 56);
+ binary[1] = (byte) (value >> 48);
+ binary[2] = (byte) (value >> 40);
+ binary[3] = (byte) (value >> 32);
+ binary[4] = (byte) (value >> 24);
+ binary[5] = (byte) (value >> 16);
+ binary[6] = (byte) (value >> 8);
+ binary[7] = (byte) value;
+ return binary;
+ }
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|