package com.hammurapi.store.local;

import java.util.concurrent.locks.ReadWriteLock;

import com.hammurapi.extract.Predicate;
import com.hammurapi.store.AbstractStore;
import com.hammurapi.store.DeputyStore;
import com.hammurapi.store.LiveView;
import com.hammurapi.store.UnmodifiableStore;

/**
 * In-memory object store.
 * @author Pavel Vlasov
 *
 * @param <T>
 */
public class LocalStoreImpl<T, PK> extends LocalStoreBase<T, PK, LocalStore<T,PK>> implements LocalStore<T, PK> {


	public LocalStoreImpl(Config<T, PK, LocalStore<T, PK>> config) {
		super(config);
	}
	
	protected static class LocalDeputyStore<T, PK> extends DeputyStore<T, PK, LocalStore<T,PK>> implements LocalStore<T,PK> {

		public LocalDeputyStore(AbstractStore<T, PK, LocalStore<T, PK>> master,	ReadWriteLock masterLock) {
			super(master, masterLock);
		}

		@Override
		protected LocalStore<T, PK> createDeputy() {
			return new LocalDeputyStore<T, PK>(this, createMasterLock());
		}
		
		@Override
		public LocalStore<T, PK> createUnmodifiableFacade() {
			return new LocalUnmodifiableStore<T, PK>(this);
		}

		@Override
		protected LocalStore<T, PK> createLiveView(Predicate<T, LocalStore<T, PK>> selector) {
			return new LocalLiveView<T, PK>(this, selector);
		}
		
	}
	
	protected static class LocalUnmodifiableStore<T, PK> extends UnmodifiableStore<T, PK, LocalStore<T, PK>> implements LocalStore<T, PK> {

		public LocalUnmodifiableStore(LocalStore<T, PK> master) {
			super(master);
		}
		
	}
	
	protected static class LocalLiveView<T, PK> extends LiveView<T, PK, LocalStore<T, PK>> implements LocalStore<T, PK> {

		public LocalLiveView(LocalStore<T, PK> master, Predicate<T, LocalStore<T, PK>> selector) {
			super(master, selector);
		}
		
		@Override
		public LocalStore<T, PK> createUnmodifiableFacade() {
			return new LocalUnmodifiableStore<T, PK>(this);
		}
		
	}

	@Override
	protected LocalStore<T, PK> createDeputy() {
		return new LocalDeputyStore<T,PK>(this, createMasterLock());
	}
	
	@Override
	public LocalStore<T, PK> createUnmodifiableFacade() {
		return new LocalUnmodifiableStore<T, PK>(this);
	}

	@Override
	protected LocalStore<T, PK> createLiveView(Predicate<T, LocalStore<T, PK>> selector) {
		return new LocalLiveView<T,PK>(this, selector);
	}
	
}
