/* * Copyright 2008-2009 LinkedIn, Inc * * 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 voldemort.store.serialized; import java.util.List; import voldemort.serialization.Serializer; import voldemort.server.storage.KeyLockHandle; import voldemort.store.StorageEngine; import voldemort.utils.ByteArray; import voldemort.utils.ClosableIterator; import voldemort.utils.Pair; import voldemort.utils.Utils; import voldemort.versioning.Versioned; /** * A StorageEngine that handles serialization to bytes, transforming each * request to a request to StorageEngine<byte[],byte[], byte[]> * * * @param <K> The key type * @param <V> The value type * @param <T> the transforms type */ public class SerializingStorageEngine<K, V, T> extends SerializingStore<K, V, T> implements StorageEngine<K, V, T> { private final StorageEngine<ByteArray, byte[], byte[]> storageEngine; public SerializingStorageEngine(StorageEngine<ByteArray, byte[], byte[]> innerStorageEngine, Serializer<K> keySerializer, Serializer<V> valueSerializer, Serializer<T> transformsSerializer) { super(innerStorageEngine, keySerializer, valueSerializer, transformsSerializer); this.storageEngine = Utils.notNull(innerStorageEngine); } public static <K1, V1, T1> SerializingStorageEngine<K1, V1, T1> wrap(StorageEngine<ByteArray, byte[], byte[]> s, Serializer<K1> k, Serializer<V1> v, Serializer<T1> t) { return new SerializingStorageEngine<K1, V1, T1>(s, k, v, t); } @Override public ClosableIterator<Pair<K, Versioned<V>>> entries() { return new EntriesIterator(storageEngine.entries()); } @Override public ClosableIterator<K> keys() { return new KeysIterator(storageEngine.keys()); } @Override public ClosableIterator<Pair<K, Versioned<V>>> entries(int partition) { return new EntriesIterator(storageEngine.entries(partition)); } @Override public ClosableIterator<K> keys(int partition) { return new KeysIterator(storageEngine.keys(partition)); } @Override public void truncate() { storageEngine.truncate(); } private class KeysIterator implements ClosableIterator<K> { private final ClosableIterator<ByteArray> iterator; public KeysIterator(ClosableIterator<ByteArray> iterator) { this.iterator = iterator; } @Override public boolean hasNext() { return iterator.hasNext(); } @Override public K next() { ByteArray key = iterator.next(); if(key == null) return null; return getKeySerializer().toObject(key.get()); } @Override public void remove() { iterator.remove(); } @Override public void close() { iterator.close(); } } private class EntriesIterator implements ClosableIterator<Pair<K, Versioned<V>>> { private final ClosableIterator<Pair<ByteArray, Versioned<byte[]>>> iterator; public EntriesIterator(ClosableIterator<Pair<ByteArray, Versioned<byte[]>>> iterator) { this.iterator = iterator; } @Override public boolean hasNext() { return iterator.hasNext(); } @Override public Pair<K, Versioned<V>> next() { Pair<ByteArray, Versioned<byte[]>> keyAndVal = iterator.next(); if(keyAndVal == null) { return null; } else { Versioned<byte[]> versioned = keyAndVal.getSecond(); return Pair.create(getKeySerializer().toObject(keyAndVal.getFirst().get()), new Versioned<V>(getValueSerializer().toObject(versioned.getValue()), versioned.getVersion())); } } @Override public void remove() { iterator.remove(); } @Override public void close() { iterator.close(); } } @Override public boolean isPartitionAware() { return storageEngine.isPartitionAware(); } @Override public boolean isPartitionScanSupported() { return storageEngine.isPartitionScanSupported(); } @Override public boolean beginBatchModifications() { return false; } @Override public boolean endBatchModifications() { return false; } @Override public List<Versioned<V>> multiVersionPut(K key, List<Versioned<V>> values) { throw new UnsupportedOperationException("multiVersionPut is not supported for " + this.getClass().getName()); } @Override public KeyLockHandle<V> getAndLock(K key) { throw new UnsupportedOperationException("getAndLock is not supported for " + this.getClass().getName()); } @Override public void putAndUnlock(K key, KeyLockHandle<V> handle) { throw new UnsupportedOperationException("putAndUnlock is not supported for " + this.getClass().getName()); } @Override public void releaseLock(KeyLockHandle<V> handle) { throw new UnsupportedOperationException("releaseLock is not supported for " + this.getClass().getName()); } }