FileDocCategorySizeDatePackage
StorageCoreController.javaAPI DocApache Lucene 2.1.020985Wed Feb 14 10:46:04 GMT 2007org.apache.lucene.gdata.storage.lucenestorage

StorageCoreController

public class StorageCoreController extends Object implements org.apache.lucene.gdata.storage.StorageController
author
Simon Willnauer

Fields Summary
protected static final Log
LOG
private IndexSearcher
searcher
private Directory
storageDir
private StorageModifier
modifier
private org.apache.lucene.gdata.utils.ReferenceCounter
storageQuery
private StorageBuffer
currentBuffer
private final AtomicBoolean
isClosed
private final ReentrantLock
storageControllerLock
private final Condition
closeCondition
private static final int
DEFAULT_STORAGE_BUFFER_SIZE
private static final int
DEFAULT_STORAGE_PERSIST_FACTOR
private static final String
RECOVERDIRECTORY
private static final String
STORAGELOG
private org.apache.lucene.gdata.storage.IDGenerator
idGenerator
private final ConcurrentStorageLock
storageLock
private int
indexOptimizeInterval
private String
storageDirectory
private boolean
keepRecoveredFiles
private boolean
recover
private int
storageBufferSize
private int
storagePersistFactor
private org.apache.lucene.gdata.storage.lucenestorage.recover.RecoverController
recoverController
Constructors Summary
public StorageCoreController()
Creates a new StoragCoreController

        this.closeCondition = this.storageControllerLock.newCondition();
        this.storageLock = SingleHostConcurrentStorageLock.getConcurrentStorageLock();

    
Methods Summary
private voidclose()

    	if(this.isClosed.get())
    		throw new IllegalStateException("StorageController is already closed -- server is shutting down");
    	
        this.storageControllerLock.lock();
        try{
        	if(this.isClosed.get())
        		throw new IllegalStateException("StorageController is already closed -- server is shutting down");
        	this.isClosed.set(true);
        	while(this.storageControllerLock.getQueueLength()>0)
        		try{
        		this.closeCondition.await();
        		}catch (Exception e) {
					//
				}
            if (LOG.isInfoEnabled())
                LOG.info("StorageController has been closed -- server is shutting down -- release all resources");
            if (this.storageQuery != null)
                this.storageQuery.decrementRef();
            if(this.recoverController != null)
                this.recoverController.destroy();
            this.storageLock.close();
            this.modifier.close();
            this.idGenerator.stopIDGenerator();
		}finally{
        	this.storageControllerLock.unlock();
        }
    
private voidcreateAdminAccount()

        GDataAccount adminAccount = GDataAccount.createAdminAccount();
        StorageAccountWrapper wrapper = new StorageAccountWrapper(adminAccount);
        this.getStorageModifier().createAccount(wrapper);
    
protected org.apache.lucene.index.IndexModifiercreateIndexModifier()
Creates a new IndexModifier on the storage index

return
- a new modifier
throws
IOException - if an IO exception occurs

    	if(this.isClosed.get())
    		throw new IllegalStateException("StorageController is already closed -- server is shutting down");
        this.storageControllerLock.lock();
        try{
        	if(this.isClosed.get())
        		throw new IllegalStateException("StorageController is already closed -- server is shutting down");
	        if (LOG.isInfoEnabled())
	            LOG.info("new IndexModifier created - release to StorageModifier");
        
            return new IndexModifier(this.storageDir, new StandardAnalyzer(),
                    false);
        }finally{
            try{
                this.closeCondition.signalAll();
                }catch (Throwable e) {/**/}
        	this.storageControllerLock.unlock();
        }
    
private booleancreateLuceneStorageLog(java.io.File directory)

        if (directory.isDirectory() && !directory.exists()) {
            if(!directory.createNewFile())
                throw new StorageException("Can not create directory -- "+directory);
        }
        File file = new File(directory.getAbsolutePath()
                + System.getProperty("file.separator") + STORAGELOG);
        return file.createNewFile();

    
private org.apache.lucene.gdata.storage.lucenestorage.recover.RecoverControllercreateRecoverController(boolean doRecover, boolean keepfiles)

        String recoverDirectory = null;
        if(this.storageDirectory.endsWith("/") || this.storageDirectory.endsWith("\\"))
            recoverDirectory = this.storageDirectory.substring(0,this.storageDirectory.length()-1)+System.getProperty("file.separator")+RECOVERDIRECTORY;
        else
            recoverDirectory = this.storageDirectory+System.getProperty("file.separator")+RECOVERDIRECTORY;
        File recoverDirectoryFile = new File(recoverDirectory);
       return new RecoverController(recoverDirectoryFile,doRecover,keepfiles);
    
private StorageModifiercreateStorageModifier(boolean create)

        IndexModifier indexModifier = new IndexModifier(this.storageDir,
                new StandardAnalyzer(), create);
        return new StorageModifier(this, indexModifier, this.currentBuffer,
                this.storagePersistFactor, this.indexOptimizeInterval);
    
public voiddestroy()

see
org.apache.lucene.gdata.storage.StorageController#destroy()

        try {
            close();
        } catch (Exception e) {
            LOG.error("Closing StorageCoreController failed -- "
                    + e.getMessage(), e);
        }
    
public voidforceWrite()
Forces the StorageModifier to write all buffered changes.

throws
IOException - if an IO exception occurs

    	if(this.isClosed.get())
    		throw new IllegalStateException("StorageController is already closed -- server is shutting down");
        this.modifier.forceWrite();
    
public intgetBufferSize()
The size of the StorageBuffer.

return
- storage buffer size

        return this.storageBufferSize;
    
protected org.apache.lucene.store.DirectorygetDirectory()

return
- the lucene directory used as a storage

        return this.storageDir;
    
public intgetIndexOptimizeInterval()

return
Returns the indexOptimizeInterval.

        return this.indexOptimizeInterval;
    
protected ConcurrentStorageLockgetLock()

        return this.storageLock;
    
private org.apache.lucene.gdata.utils.ReferenceCountergetNewStorageQueryHolder(StorageQuery query)

        ReferenceCounter<StorageQuery> holder = new ReferenceCounter<StorageQuery>(
                query) {
            @Override
			public void close() {
                try {
                    if (LOG.isInfoEnabled())
                        LOG
                                .info("close StorageQuery -- zero references remaining");
                    this.resource.close();
                } catch (IOException e) {
                    LOG.warn("Error during close call on StorageQuery"
                            + e.getMessage(), e);
                }
            }
        };
        holder.increamentReference();
        return holder;
    
public intgetPersistFactor()
An integer value after how many changes to the StorageModifier the buffered changes will be persisted / written to the index

return
- the persist factor

        return this.storagePersistFactor;
    
public org.apache.lucene.gdata.storage.StoragegetStorage()

see
org.apache.lucene.gdata.storage.StorageController#getStorage()

        try {
            return new StorageImplementation();
        } catch (StorageException e) {
            StorageException ex = new StorageException(
                    "Can't create Storage instance -- " + e.getMessage(), e);
            ex.setStackTrace(e.getStackTrace());
            throw ex;

        }
    
protected StorageModifiergetStorageModifier()
returns the current storage modifier

return
- the current storage modifier

        return this.modifier;
    
protected org.apache.lucene.gdata.utils.ReferenceCountergetStorageQuery()
returns a StorageQuery to query the storage index. The returned object is a reference counter to keep track of the references to the StorageQuery. The reference is already incremented before returned from this method.

if the reference counter has no remaining references the resource e.g. the StorageQuery will be closed. This ensures that a StorageQuery instance will be around as long as needed and the resources will be released. The reference counter should be decremented by clients after finished using the query instance.

return
a {@link ReferenceCounter} instance holding the StorageQuery as a resource.

    	if(this.isClosed.get())
    		throw new IllegalStateException("StorageController is already closed -- server is shutting down");
        this.storageControllerLock.lock();
        try{
        	if(this.isClosed.get())
        		throw new IllegalStateException("StorageController is already closed -- server is shutting down");
            if (this.storageQuery == null) {
                this.storageQuery = getNewStorageQueryHolder(new StorageQuery(
                        this.currentBuffer, this.searcher));
                if (LOG.isInfoEnabled())
                    LOG.info("Release new StorageQuery");
            }
            this.storageQuery.increamentReference();
            return this.storageQuery;
        }finally{
            try{
        	this.closeCondition.signalAll();
            }catch (Throwable e) {/**/}
        	this.storageControllerLock.unlock();
        }
    
public voidinitialize()

see
org.apache.lucene.gdata.server.registry.ServerComponent#initialize()

           
       
        synchronized (StorageCoreController.class) {
         
            try {
                this.idGenerator = new IDGenerator(10);
            } catch (Exception e) {
                throw new StorageException("Can't create ID Generator", e);
            }

            boolean createNewStorage = false;
          
            if (this.storageDir == null) {

                
                File storeDir = new File(this.storageDirectory);
                File storageLog = new File(storeDir.getAbsolutePath()
                        + System.getProperty("file.separator") + STORAGELOG);
                try {
                    if (storeDir.isDirectory() && !storageLog.exists()) {

                        if (createLuceneStorageLog(storeDir)) {
                            this.storageDir = FSDirectory.getDirectory(
                                    storeDir, true);
                            createNewStorage = true;
                        } else
                            throw new StorageException(
                                    "could not create storage lock file in "
                                            + this.storageDirectory);

                    } else
                        this.storageDir = FSDirectory.getDirectory(storeDir,
                                false);
                } catch (IOException e) {
                    storageLog.delete();
                    throw new StorageException(e);
                }
                
                this.storageBufferSize = this.storageBufferSize < DEFAULT_STORAGE_BUFFER_SIZE ? DEFAULT_STORAGE_BUFFER_SIZE
                        : this.storageBufferSize;
                this.storagePersistFactor = this.storagePersistFactor < DEFAULT_STORAGE_PERSIST_FACTOR ? DEFAULT_STORAGE_PERSIST_FACTOR
                        : this.storagePersistFactor;

            }else
                createNewStorage = true;
               

            this.currentBuffer = new StorageBuffer(this.storageBufferSize);
            try{
            this.modifier = createStorageModifier(createNewStorage);
            this.searcher = new IndexSearcher(this.storageDir);
            }catch (Exception e) {
               throw new StorageException("Can not create Searcher/Modifier -- "+e.getMessage(),e);
            }
           
            
            if(createNewStorage)
                createAdminAccount();
            if(!this.recover)
                return;
            try{
            tryRecover();
            }catch (Exception e) {
                LOG.fatal("Recovering failed",e);
                throw new StorageException("Recovering failed -- "+e.getMessage(),e); 
            }
            
            this.recoverController = createRecoverController(false,false);
            try{
            this.recoverController.initialize();
            }catch (Exception e) {
                LOG.fatal("Can not initialize recover controller",e);
                throw new StorageException("Can not initialize recover controller -- "+e.getMessage(),e);
            }

        }
    
public booleanisKeepRecoveredFiles()

return
Returns the keepRecoveredFiles.

        return this.keepRecoveredFiles;
    
public booleanisRecover()

return
Returns the recover.

        return this.recover;
    
protected voidregisterNewRecoverWriter()

        if(this.recoverController == null || this.recoverController.isRecovering())
            return;
        this.recoverController.destroy();
        this.recoverController = createRecoverController(false,false);
        this.recoverController.initialize();
            
    
protected voidregisterNewStorageQuery()
Forces the controller to register a new StorageQuery instance. This method will be called after an index has been modified to make the changes available for searching.

throws
IOException - if an IO exception occurs

    	if(this.isClosed.get())
    		throw new IllegalStateException("StorageController is already closed -- server is shutting down");
        this.storageControllerLock.lock();
        try{
        	if(this.isClosed.get())
        		throw new IllegalStateException("StorageController is already closed -- server is shutting down");
	        if (LOG.isInfoEnabled())
	            LOG.info("new StorageQuery requested -- create new storage buffer");
        
            if (this.storageQuery != null)
                this.storageQuery.decrementRef();
            this.searcher = new IndexSearcher(this.storageDir);
            this.storageQuery = null;
            this.currentBuffer = new StorageBuffer(this.storageBufferSize);

        }finally{
            try{
                this.closeCondition.signalAll();
                }catch (Throwable e) {/**/}
        	this.storageControllerLock.unlock();
        }

    
public synchronized java.lang.StringreleaseId()
Creates a unique ID to store as an id for {@link org.apache.lucene.gdata.data.ServerBaseEntry} instances

return
- a unique id
throws
StorageException - if no id can be released

        try {
            return this.idGenerator.getUID();
        } catch (InterruptedException e) {
            throw new StorageException("Can't release new ID", e);
        }

    
protected StorageBufferreleaseNewStorageBuffer()
Creates a new StorageBuffer

return
the new StorageBuffer

    	if(this.isClosed.get())
    		throw new IllegalStateException("StorageController is already closed -- server is shutting down");
        this.storageControllerLock.lock();
        try{
        	if(this.isClosed.get())
        		throw new IllegalStateException("StorageController is already closed -- server is shutting down");
            return this.currentBuffer;
        }finally{
            try{
        	this.closeCondition.signalAll();
            }catch (Throwable e) {/**/}
        	this.storageControllerLock.unlock();
        }
    
public voidsetBufferSize(int storageBufferSize)
The size of the StorageBuffer. This size should be at least as big as the persist factor to prevent the StorageBuffer from resizing

param
storageBufferSize

        this.storageBufferSize = storageBufferSize;
    
public voidsetDirectory(java.lang.String storageDirectory)

param
storageDirectory The storageDirectory to set.

        this.storageDirectory = storageDirectory;
    
public voidsetKeepRecoveredFiles(boolean keepRecoveredFiles)

param
keepRecoveredFiles The keepRecoveredFiles to set.

        this.keepRecoveredFiles = keepRecoveredFiles;
    
public voidsetOptimizeInterval(int indexOptimizeInterval)

param
indexOptimizeInterval The indexOptimizeInterval to set.

        this.indexOptimizeInterval = indexOptimizeInterval;
    
public voidsetPersistFactor(int storagePersistFactor)

param
storagePersistFactor

        this.storagePersistFactor = storagePersistFactor;
    
public voidsetRecover(boolean recover)

param
recover The recover to set.

        this.recover = recover;
    
public voidsetStorageDir(org.apache.lucene.store.Directory storageDir)

param
storageDir The storageDir to set.

        this.storageDir = storageDir;
    
private voidtryRecover()

        if(!this.recover)
            return;
        LOG.info("try to recover files if there are any");
        this.recoverController = createRecoverController(true,false);
        this.recoverController.initialize();
        this.recoverController.recoverEntries(this.modifier);
        this.recoverController.destroy();
    
protected voidwriteRecoverEntry(StorageEntryWrapper wrapper)

        if(this.recoverController!= null &&!this.recoverController.isRecovering() )
            this.recoverController.storageModified(wrapper);