summaryrefslogtreecommitdiff
path: root/src/main/java/com/amazon/carbonado/spi
diff options
context:
space:
mode:
authorBrian S. O'Neill <bronee@gmail.com>2006-10-15 17:50:08 +0000
committerBrian S. O'Neill <bronee@gmail.com>2006-10-15 17:50:08 +0000
commitf0ec30fd9cc7fa19f9f9bf82d7d7449a65d90359 (patch)
treeffb5f5fecb4282f1bdb6e8bbb3e572f256310a70 /src/main/java/com/amazon/carbonado/spi
parent4ceddfc456e83a79e782599b5b86b68e38b6ef94 (diff)
Created StorageCollection.
More tests added.
Diffstat (limited to 'src/main/java/com/amazon/carbonado/spi')
-rw-r--r--src/main/java/com/amazon/carbonado/spi/StorageCollection.java113
1 files changed, 113 insertions, 0 deletions
diff --git a/src/main/java/com/amazon/carbonado/spi/StorageCollection.java b/src/main/java/com/amazon/carbonado/spi/StorageCollection.java
new file mode 100644
index 0000000..f0d38ad
--- /dev/null
+++ b/src/main/java/com/amazon/carbonado/spi/StorageCollection.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2006 Amazon Technologies, Inc. or its affiliates.
+ * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks
+ * of Amazon Technologies, Inc. or its affiliates. All rights reserved.
+ *
+ * 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.amazon.carbonado.spi;
+
+import java.util.IdentityHashMap;
+import java.util.Map;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+import com.amazon.carbonado.MalformedTypeException;
+import com.amazon.carbonado.RepositoryException;
+import com.amazon.carbonado.Storable;
+import com.amazon.carbonado.Storage;
+import com.amazon.carbonado.SupportException;
+
+import com.amazon.carbonado.info.StorableIntrospector;
+
+/**
+ * Thread-safe container of Storage instances which creates Storage
+ * on-demand. If multiple threads are requesting the same Storage concurrently,
+ * only one thread actually creates the Storage. The other waits for it to
+ * become available.
+ *
+ * @author Brian S O'Neill
+ */
+public abstract class StorageCollection {
+ private final Map<Class<?>, Storage> mStorageMap;
+ private final Map<Class<?>, Object> mStorableTypeLockMap;
+
+ public StorageCollection() {
+ mStorageMap = new ConcurrentHashMap<Class<?>, Storage>();
+ mStorableTypeLockMap = new IdentityHashMap<Class<?>, Object>();
+ }
+
+ public <S extends Storable> Storage<S> storageFor(Class<S> type)
+ throws MalformedTypeException, SupportException, RepositoryException
+ {
+ Storage storage = mStorageMap.get(type);
+ if (storage != null) {
+ return storage;
+ }
+
+ Object lock;
+ boolean doCreate;
+
+ synchronized (mStorableTypeLockMap) {
+ lock = mStorableTypeLockMap.get(type);
+ if (lock != null) {
+ doCreate = false;
+ } else {
+ doCreate = true;
+ lock = new Object();
+ mStorableTypeLockMap.put(type, lock);
+ }
+ }
+
+ synchronized (lock) {
+ // Check storage map again before creating new storage.
+ while (true) {
+ storage = mStorageMap.get(type);
+ if (storage != null) {
+ return storage;
+ }
+ if (doCreate) {
+ break;
+ }
+ try {
+ lock.wait();
+ } catch (InterruptedException e) {
+ throw new RepositoryException("Interrupted");
+ }
+ }
+
+ // Examine and throw exception early if there is a problem.
+ StorableIntrospector.examine(type);
+
+ storage = createStorage(type);
+
+ mStorageMap.put(type, storage);
+ lock.notifyAll();
+ }
+
+ // Storable type lock no longer needed.
+ synchronized (mStorableTypeLockMap) {
+ mStorableTypeLockMap.remove(type);
+ }
+
+ return storage;
+ }
+
+ public Iterable<Storage> allStorage() {
+ return mStorageMap.values();
+ }
+
+ protected abstract <S extends Storable> Storage<S> createStorage(Class<S> type)
+ throws SupportException, RepositoryException;
+}