diff options
| author | Brian S. O'Neill <bronee@gmail.com> | 2006-10-15 17:50:08 +0000 | 
|---|---|---|
| committer | Brian S. O'Neill <bronee@gmail.com> | 2006-10-15 17:50:08 +0000 | 
| commit | f0ec30fd9cc7fa19f9f9bf82d7d7449a65d90359 (patch) | |
| tree | ffb5f5fecb4282f1bdb6e8bbb3e572f256310a70 /src/main/java/com/amazon/carbonado/spi | |
| parent | 4ceddfc456e83a79e782599b5b86b68e38b6ef94 (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.java | 113 | 
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;
 +}
 | 
