Permalink
Browse files

Added plug-in loader

  • Loading branch information...
tzaeschke committed Sep 28, 2017
1 parent 380e1e9 commit 43af8b879cdcfdb2f069c0c66779e5995f466a80
View
@@ -1,12 +1,16 @@
CHANGELOG
2017-Sep-28
===========
- T.Zaeschke
- Added plug-in loader, see PluginLoader for usage.
2017-Sep-09
===========
- T.Zaeschke
- Refactored serverside concurrency, this also resolves issue #105
2017-Jun-25
===========
- T.Zaeschke
@@ -41,6 +41,7 @@
import org.zoodb.api.impl.ZooPC;
import org.zoodb.internal.client.SchemaManager;
import org.zoodb.internal.client.session.ClientSessionCache;
import org.zoodb.internal.plugin.PluginLoader;
import org.zoodb.internal.server.OptimisticTransactionResult;
import org.zoodb.internal.server.TxObjInfo;
import org.zoodb.internal.util.ClientLock;
@@ -86,6 +87,10 @@
private final WeakHashMap<Closeable, Object> resources = new WeakHashMap<>();
static {
PluginLoader.activatePlugins();
}
public Session(String dbPath, SessionConfig config) {
this(null, dbPath, config);
}
@@ -0,0 +1,112 @@
/*
* Copyright 2009-2016 Tilmann Zaeschke. All rights reserved.
*
* This file is part of ZooDB.
*
* ZooDB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ZooDB 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ZooDB. If not, see <http://www.gnu.org/licenses/>.
*
* See the README and COPYING files for further information.
*/
package org.zoodb.internal.plugin;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.Enumeration;
import java.util.concurrent.atomic.AtomicBoolean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.zoodb.internal.util.DBLogger;
/**
* Plug-in initializer for ZooDB plug-ins.
*
* To register a plugin for activation, put a file into the packaged jar.
* The file goes into: META-INF/services/org.zoodb.spi.ZooPluginActivator
* The file should contain the class name of an activator class that
* has a static 'activate()' method.
* This class and method will be detected by ZooDB and will be executed.
* The activate() method can then register the plugin. For examples, look at the
* zoodb-profiler or zoodb-server-btree plugins.
*
* @author Tilmann Zäschke
*
*/
public class PluginLoader {
public static final String SERVICE_RESOURCE_NAME =
"META-INF/services/org.zoodb.spi.ZooPluginActivator";
private static final Logger LOGGER = LoggerFactory.getLogger(PluginLoader.class);
private static final AtomicBoolean hasBeenRun = new AtomicBoolean(false);
private PluginLoader() {
// private
}
public static void activatePlugins() {
if (!hasBeenRun.compareAndSet(false, true)) {
//already activated
return;
}
Enumeration<URL> urls;
try {
urls = ClassLoader.getSystemResources(SERVICE_RESOURCE_NAME);
} catch (IOException e) {
throw DBLogger.wrap(e);
}
while (urls.hasMoreElements()) {
try {
String className = getClassNameFromURL( (URL) urls.nextElement());
Class<?> implClass = Class.forName(className);
Method m = implClass.getMethod("activate");
m.invoke(null);
LOGGER.info("Loading plug-in: {}", className);
} catch (Exception e) {
throw DBLogger.wrap(e);
}
}
}
private static String getClassNameFromURL (URL url) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()))) {
String line = null;
while ((line = reader.readLine()) != null) {
line = line.trim();
if (line.length() == 0 || line.startsWith("#")) {
continue;
}
return line.split("\\s")[0];
// String[] tokens = line.split("\\s");
// String className = tokens[0];
// int indexOfComment = className.indexOf('#');
// if (indexOfComment == -1) {
// return className;
// }
// return className.substring(0, indexOfComment);
}
return null;
} catch (IOException e) {
throw DBLogger.wrap(e);
}
}
}
@@ -32,6 +32,7 @@
import org.slf4j.LoggerFactory;
import org.zoodb.internal.Node;
import org.zoodb.internal.client.AbstractCache;
import org.zoodb.internal.plugin.PluginLoader;
import org.zoodb.internal.util.DBLogger;
/**
@@ -58,6 +59,10 @@
private static List<SessionManager> sessions = new ArrayList<>();
static {
PluginLoader.activatePlugins();
}
public static DiskAccessOneFile getSession(Node node, AbstractCache cache) {
String dbPath = node.getDbPath();
LOGGER.info("Opening DB file: {}", dbPath);
@@ -25,13 +25,53 @@
public class IndexFactory {
public static interface CreateIndex<R> {
R create(PAGE_TYPE type, IOResourceProvider storage);
}
public static interface LoadIndex<R> {
R load(PAGE_TYPE type, IOResourceProvider storage, int pageId);
}
public static interface CreateIndexSized<R> {
R create(PAGE_TYPE type, IOResourceProvider storage, int keySize, int valSize);
}
public static interface LoadIndexSized<R> {
R load(PAGE_TYPE type, IOResourceProvider storage, int pageId, int keySize, int valSize);
}
private static final CreateIndex<LongLongIndex> DEFAULT_CREATE_INDEX = PagedLongLong::new;
private static final LoadIndex<LongLongIndex> DEFAULT_LOAD_INDEX = PagedLongLong::new;
private static final CreateIndex<LongLongIndex.LongLongUIndex> DEFAULT_CREATE_UNIQUE_INDEX =
PagedUniqueLongLong::new;
private static final LoadIndex<LongLongIndex.LongLongUIndex> DEFAULT_LOAD_UNIQUE_INDEX =
PagedUniqueLongLong::new;
private static final CreateIndexSized<LongLongIndex.LongLongUIndex> DEFAULT_CREATE_UNIQUE_INDEX_SIZED =
PagedUniqueLongLong::new;
private static final LoadIndexSized<LongLongIndex.LongLongUIndex> DEFAULT_LOAD_UNIQUE_INDEX_SIZED =
PagedUniqueLongLong::new;
public static volatile CreateIndex<LongLongIndex> CREATE_INDEX = DEFAULT_CREATE_INDEX;
public static volatile CreateIndex<LongLongIndex.LongLongUIndex> CREATE_UNIQUE_INDEX = DEFAULT_CREATE_UNIQUE_INDEX;
public static volatile LoadIndex<LongLongIndex> LOAD_INDEX = DEFAULT_LOAD_INDEX;
public static volatile LoadIndex<LongLongIndex.LongLongUIndex> LOAD_UNIQUE_INDEX = DEFAULT_LOAD_UNIQUE_INDEX;
public static volatile CreateIndexSized<LongLongIndex.LongLongUIndex> CREATE_UNIQUE_INDEX_SIZED =
DEFAULT_CREATE_UNIQUE_INDEX_SIZED;
public static volatile LoadIndexSized<LongLongIndex.LongLongUIndex> LOAD_UNIQUE_INDEX_SIZED =
DEFAULT_LOAD_UNIQUE_INDEX_SIZED;
private IndexFactory() {
//private
}
/**
* @param type The page type for index pages
* @param storage The output stream
* @return a new index
*/
public static LongLongIndex createIndex(PAGE_TYPE type, IOResourceProvider storage) {
return new PagedLongLong(type, storage);
return CREATE_INDEX.create(type, storage);
}
/**
@@ -41,7 +81,7 @@ public static LongLongIndex createIndex(PAGE_TYPE type, IOResourceProvider stora
* @return an index reconstructed from disk
*/
public static LongLongIndex loadIndex(PAGE_TYPE type, IOResourceProvider storage, int pageId) {
return new PagedLongLong(type, storage, pageId);
return LOAD_INDEX.load(type, storage, pageId);
}
/**
@@ -51,7 +91,7 @@ public static LongLongIndex loadIndex(PAGE_TYPE type, IOResourceProvider storage
*/
public static LongLongIndex.LongLongUIndex createUniqueIndex(PAGE_TYPE type,
IOResourceProvider storage) {
return new PagedUniqueLongLong(type, storage);
return CREATE_UNIQUE_INDEX.create(type, storage);
}
/**
@@ -62,7 +102,7 @@ public static LongLongIndex loadIndex(PAGE_TYPE type, IOResourceProvider storage
*/
public static LongLongIndex.LongLongUIndex loadUniqueIndex(PAGE_TYPE type,
IOResourceProvider storage, int pageId) {
return new PagedUniqueLongLong(type, storage, pageId);
return LOAD_UNIQUE_INDEX.load(type, storage, pageId);
}
/**
@@ -75,7 +115,7 @@ public static LongLongIndex loadIndex(PAGE_TYPE type, IOResourceProvider storage
*/
public static LongLongIndex.LongLongUIndex createUniqueIndex(PAGE_TYPE type,
IOResourceProvider storage, int keySize, int valSize) {
return new PagedUniqueLongLong(type, storage, keySize, valSize);
return CREATE_UNIQUE_INDEX_SIZED.create(type, storage, keySize, valSize);
}
/**
@@ -89,7 +129,7 @@ public static LongLongIndex loadIndex(PAGE_TYPE type, IOResourceProvider storage
*/
public static LongLongIndex.LongLongUIndex loadUniqueIndex(PAGE_TYPE type,
IOResourceProvider storage, int pageId, int keySize, int valSize) {
return new PagedUniqueLongLong(type, storage, pageId, keySize, valSize);
return LOAD_UNIQUE_INDEX_SIZED.load(type, storage, pageId, keySize, valSize);
}
}
@@ -191,4 +191,8 @@ public static boolean isFatalDataStoreException(RuntimeException e) {
public static boolean isOptimisticVerificationException(RuntimeException e) {
return OPTIMISTIC_VERIFICATION_EXCEPTION.isAssignableFrom(e.getClass());
}
public static RuntimeException wrap(Exception e) {
return new RuntimeException(e);
}
}

0 comments on commit 43af8b8

Please sign in to comment.