Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package com.fasterxml.clustermate.service.store;
  
  import java.io.File;
  
  import org.slf4j.Logger;
 
 
 
 
 
 public abstract class StoresImpl<K extends EntryKey, E extends StoredEntry<K>>
 	extends Stores<K, E>
 {
     private final Logger LOG = LoggerFactory.getLogger(getClass());

    
For Node stores we do not really need much any caching; but give half a meg just to keep branch nodes in memory.
 
     private final static long NODE_BDB_CACHE_SIZE = 512L * 1024L;

    
Last-accessed can benefit more from cache, give it 20 megs for now
 
     private final static long LAST_ACCESS_BDB_CACHE_SIZE = 20L * 1024L * 1024L;

    
Last-access table may get rather high concurrency as it may be updated for every GET request, so let's boost from 1 to reasonably high prime number.
 
     protected final static int DEFAULT_LAST_ACCESS_LOCK_TABLES = 17;
 
     /*
     /**********************************************************************
     /* Configuration
     /**********************************************************************
      */
 
     protected final TimeMaster _timeMaster;
 
     protected final ObjectMapper _jsonMapper;
    
    
Directory that contains environment used for storing state information for this node instance and its peers. Separate from other storage to reduce likelihood of corruption; handling of node data is fully transactional as it should be less likely to corrupt, ever.
 
     private final File _bdbRootForNodes;

    
Directory for environment used for storing last-accessed information.
 
     private final File _bdbRootForLastAccess;
 
     /*
     /**********************************************************************
     /* Stores
     /**********************************************************************
      */
    
    
Separately managed com.fasterxml.storemate.store.StorableStore that handles actual entry storage details.
 
     protected final StorableStore _entryStore;

    
We also need a factory for converting keys, entries.
 
     protected final StoredEntryConverter<K,E,?> _entryConverter;
     
     // Separate Environments for node state, last-accessed: latter much bigger,
     // former possibly transactional
     
     private Environment _nodeEnv;
 
     private NodeStateStore _nodeStore;
 
     private Environment _lastAccessEnv;
    private LastAccessStore<K, E> _lastAccessStore;
    /*
    /**********************************************************************
    /* Status
    /**********************************************************************
     */

    
Marker flag used to indicate whether this store is currently active and able to process things.
    protected final AtomicBoolean _active = new AtomicBoolean(false);

    
Error message used to indicate why initialization failed, if it did.
    protected volatile String _initProblem;
    /*
    /**********************************************************************
    /* Basic life-cycle
    /**********************************************************************
     */
     
    public StoresImpl(ServiceConfig configTimeMaster timeMasterObjectMapper jsonMapper,
            StoredEntryConverter<K,E,?> entryConverter,
            StorableStore entryStoreFile bdbEnvRoot)
    {
         = timeMaster;
         = jsonMapper;
         = entryConverter;
         = entryStore;
        if (bdbEnvRoot == null) {
            bdbEnvRoot = config.metadataDirectory;
        }
         = new File(bdbEnvRoot"nodes");
         = new File(bdbEnvRoot"lastAccess");        
    }
    @Override
    public void start() throws IOException {
        // nothing much to do here; we actually force init on construction
    }
    @Override
    public void stop() throws IOException
    {
        .set(false);
        // close node store first, more important to preserve:
        if ( == null) {
            .warn("Odd: Node store not open? Skipping");
        } else {
            .info("Closing Node store...");
            try {
                .stop();
                .info("Closing Node store environment...");
                .close();
            } catch (Exception e) {
                .error("Problems closing node store: {}"e.getMessage(), e);
            }
        }
        // then entry metadata
        if ( == null) {
            .warn("Odd: Entry Metadata store not open? Skipping");
        } else {
            .info("Closing Entry metadata store...");
            try {
                .stop();
            } catch (Exception e) {
                .error("Problems closing Entry Metadata store: {}"e.getMessage(), e);
            }
        }
        // and finally, last-accessed (most disposable)
        if ( == null) {
            .warn("Odd: Last-access store not open? Skipping");
        } else {
            .info("Closing Last-access store...");
            try {
                .stop();
                .info("Closing Last-access environment...");
                .close();
            } catch (Exception e) {
                .error("Problems closing Last-access store: {}"e.getMessage(), e);
            }
        }
        
        .info("BDB data stores and environments closed");
    }
    
    /*
    /**********************************************************************
    /* Explicit initialization, varies for different use cases
    /**********************************************************************
     */

    
Method called to forcibly initialize environment as configured, and then open it normally.
    public boolean initAndOpen(boolean logInfo)
    {
        // first things first: must have directories for Environment
        if (!_verifyOrCreateDirectory(logInfo)
               || !_verifyOrCreateDirectory(logInfo)) {
            return false;
        }
        _openBDBs(truetruetrue);
        .set(true);
        return true;
    }
    
    
Method called to open BDB stores if they exist, in read/write mode.
    public void openIfExists()
    {
        // First: verify that the dirs exist:
        // then try opening
        _openBDBs(truefalsetrue);
        .set(true);
    }

    
Method called to open BDB stores if they exist, and only open for reading.
    public void openForReading(boolean log)
    {
        // First: verify that the dirs exist:
        // then try opening
        _openBDBs(logfalsefalse);
        .set(true);
    }
    
    protected void _openBDBs(boolean log,
          boolean allowCreateboolean writeAccess)
    {
         = null;
        final String logPrefix = allowCreate ? "Trying to open (or initialize)" : "Trying to open";
        // First, node (state) store
        if (log) {
            .info(logPrefix+" Node store...");
        }
         = new Environment(nodeEnvConfig(allowCreatewriteAccess));
        try {
             = new NodeStateStore();
        } catch (DatabaseException e) {
             = "Failed to open Node store: "+e.getMessage();
            throw new IllegalStateException(e);
        }
        if (log) {
            .info("Node store succesfully opened");
        }
        // then last access store:
        if (log) {
            .info(logPrefix+" Last-access store...");
        }
         = new Environment(lastAccessEnvConfig(allowCreatewriteAccess));
        try {
        } catch (DatabaseException e) {
             = "Failed to open Last-access store: "+e.getMessage();
            throw new IllegalStateException(e);
        }
        if (log) {
            .info("Last-access store succesfully opened");
        }
    }
    protected abstract LastAccessStore<K,E> buildAccessStore(Environment env);
    
    /*
    /**********************************************************************
    /* Simple accessors
    /**********************************************************************
     */
    @Override
    public boolean isActive() { return .get(); }
    @Override
    public String getInitProblem() { return ; }
    @Override
    public File getNodeDirectory() { return ; }
    @Override
    public StoredEntryConverter<K,E,?> getEntryConverter() { return ; }
    
    @Override
    public StorableStore getEntryStore() { return ; }
    @Override
    public NodeStateStore getNodeStore() { return ; }
    @Override
    public LastAccessStore<K, E> getLastAccessStore() { return ; }
    
    /*
    /**********************************************************************
    /* Internal methods
    /**********************************************************************
     */
    protected void _verifyDirectory(File dir)
    {
        if (!dir.exists() || !dir.isDirectory()) {
            throw new IllegalStateException("BDB path '"+dir.getAbsolutePath()
                    +"' does not point to a directory; can not open BDB -- read Documentation on how to 'init' a node!"
                    +" (usually something like './command.sh init')");
        }
    }
    
    protected boolean _verifyOrCreateDirectory(File dirboolean logInfo)
    {
        if (dir.exists()) {
            if (!dir.isDirectory()) {
                .error("There is file {} which is not directory: CAN NOT create BDB Environment!",
                        dir.getAbsolutePath());
                return false;
            }
            .info("Directory {} exists, will use it"dir.getAbsolutePath());
        } else {
            .info("Directory {} does not exist, will try to create"dir.getAbsolutePath());
            if (!dir.mkdirs()) {
                .error("FAILed to create directory {}: CAN NOT create BDB Environment!",
                        dir.getAbsolutePath());
                return false;
            }
            if (logInfo) {
                .info("Directory succesfully created");
            }
        }
        return true;
    }
    protected EnvironmentConfig nodeEnvConfig(boolean allowCreateboolean writeAccess)
    {
        EnvironmentConfig config = new EnvironmentConfig();
        config.setAllowCreate(allowCreate);
        config.setReadOnly(!writeAccess);
        config.setSharedCache(false);
        config.setCacheSize();
        config.setDurability(.);
        // default of 500 msec too low:
        config.setLockTimeout(5000L, .);
        return config;
    }
    
    protected EnvironmentConfig lastAccessEnvConfig(boolean allowCreateboolean writeAccess)
    {
        EnvironmentConfig config = new EnvironmentConfig();
        config.setAllowCreate(allowCreate);
        config.setReadOnly(!writeAccess);
        config.setSharedCache(false);
        // default of 500 msec too low:
        config.setLockTimeout(5000L, .);
        // and to get decent concurrency, default of 1 won't do:
        return config;
    }
New to GrepCode? Check out our FAQ X