com.sleepycat.je.dbi
Class DbTree

java.lang.Object
  extended by com.sleepycat.je.dbi.DbTree
All Implemented Interfaces:
Loggable

public class DbTree
extends Object
implements Loggable

DbTree represents the database directory for this environment. DbTree is itself implemented through two databases. The nameDatabase maps databaseName-> an internal databaseId. The idDatabase maps databaseId->DatabaseImpl. For example, suppose we have two databases, foo and bar. We have the following structure: nameDatabase idDatabase IN IN | | BIN BIN +-------------+--------+ +---------------+--------+ . | | . | | NameLNs NameLN NameLN MapLNs for MapLN MapLN for internal key=bar key=foo internal dbs key=53 key=79 dbs data= data= data= data= dbId79 dbId53 DatabaseImpl DatabaseImpl | | Tree for foo Tree for bar | | root IN root IN Databases, Cursors, the cleaner, compressor, and other entities have references to DatabaseImpls. It's important that object identity is properly maintained, and that all constituents reference the same DatabaseImpl for the same db, lest they develop disparate views of the in-memory database; corruption would ensue. To ensure that, all entities must obtain their DatabaseImpl by going through the idDatabase. DDL type operations such as create, rename, remove and truncate get their transactional semantics by transactionally locking the NameLN appropriately. A read-lock on the NameLN, called a handle lock, is maintained for all DBs opened via the public API (openDatabase). This prevents them from being renamed or removed while open. However, for internal database operations, no handle lock on the NameLN is acquired and MapLNs are locked with short-lived non-transactional Lockers. An entity that is trying to get a reference to the DatabaseImpl gets a short lived read lock just for the fetch of the MapLN. A write lock on the MapLN is taken when the database is created, deleted, or when the MapLN is evicted. (see DatabaseImpl.isInUse()) The nameDatabase operates pretty much as a regular application database in terms of eviction and recovery. The idDatabase requires special treatment for both eviction and recovery. The issues around eviction of the idDatabase center on the need to ensure that there are no other current references to the DatabaseImpl other than that held by the mapLN. The presence of a current reference would both make the DatabaseImpl not GC'able, and more importantly, would lead to object identify confusion later on. For example, if the MapLN is evicted while there is a current reference to its DatabaseImpl, and then refetched, there will be two in-memory versions of the DatabaseImpl. Since locks on the idDatabase are short lived, DatabaseImpl.useCount acts as a reference count of active current references. DatabaseImpl.useCount must be modified and read in conjunction with appropriate locking on the MapLN. See DatabaseImpl.isInUse() for details. This reference count checking is only needed when the entire MapLN is evicted. It's possible to evict only the root IN of the database in question, since that doesn't interfere with the DatabaseImpl object identity.


Field Summary
static DatabaseId ID_DB_ID
           
static DatabaseId NAME_DB_ID
           
static int NEG_DB_ID_START
           
static String REP_GROUP_DB_NAME
           
static String UTILIZATION_DB_NAME
           
static String VLSN_MAP_DB_NAME
           
 
Constructor Summary
DbTree()
          Create a dbTree from the log.
DbTree(EnvironmentImpl env, boolean replicationIntended)
          Create a new dbTree for a new environment.
 
Method Summary
 void close()
          Release resources and update memory budget.
 DatabaseImpl createDb(Locker locker, String databaseName, DatabaseConfig dbConfig, Database databaseHandle)
          Creates a new database object given a database name.
 DatabaseImpl createInternalDb(Locker locker, String databaseName, DatabaseConfig dbConfig)
          Create a database for internal use.
 DatabaseImpl createReplicaDb(Locker locker, String databaseName, DatabaseConfig dbConfig, NameLN replicatedLN, ReplicationContext repContext)
          Create a replicated database on this client node.
 void dbRemove(Locker locker, String databaseName, DatabaseId checkId)
          Stand alone and Master invocations.
 void dbRename(Locker locker, String databaseName, String newName)
          Stand alone and Master invocations.
(package private)  void deleteMapLN(DatabaseId id)
           
 long doTruncateDb(Locker locker, String databaseName, boolean returnCount, NameLN replicatedLN, DbOpReplicationContext repContext)
          To truncate, remove the database named by databaseName and create a new database in its place.
 void dump()
          For debugging.
 void dumpLog(StringBuilder sb, boolean verbose)
          Write the object into the string buffer for log dumping.
(package private)  String dumpString(int nSpaces)
           
 DatabaseImpl getDb(DatabaseId dbId)
          Get a database object based on an id only.
 DatabaseImpl getDb(DatabaseId dbId, long lockTimeout)
          Get a database object based on an id only.
 DatabaseImpl getDb(DatabaseId dbId, long lockTimeout, Map<DatabaseId,DatabaseImpl> dbCache)
          Get a database object based on an id only, caching the id-db mapping in the given map.
 DatabaseImpl getDb(DatabaseId dbId, long lockTimeout, String dbNameIfAvailable)
          Get a database object based on an id only.
 DatabaseImpl getDb(Locker nameLocker, String databaseName, Database databaseHandle)
          Get a database object given a database name.
 String getDbName(DatabaseId id)
          Return the database name for a given db.
 List<String> getDbNames()
           
 Map<DatabaseId,String> getDbNamesAndIds()
           
 int getHighestLevel()
           
 int getHighestLevel(DatabaseImpl dbImpl)
           
 DatabaseImpl getIdDatabaseImpl()
           
 List<String> getInternalNoLookupDbNames()
          Return a list of the names of internally used databases that don't get looked up through the naming tree.
 List<String> getInternalNoRepDbNames()
          Return a list of the names of internally used databases for all environment types.
 List<String> getInternalRepDbNames()
          Return a list of the names of internally used databases for replication only.
 int getLastLocalDbId()
          The last allocated local and replicated db ids are used for ckpts.
 int getLastReplicatedDbId()
           
 int getLogSize()
           
 long getTransactionId()
           
(package private)  long getTreeAdminMemory()
           
(package private)  void initExistingEnvironment(EnvironmentImpl eImpl)
          Initialize the db tree during recovery, after instantiating the tree from the log.
(package private)  boolean isConverted()
           
(package private)  boolean isReplicated()
           
static boolean isReservedDbName(String name)
          Returns true if the name is a reserved JE database name.
 boolean logicalEquals(Loggable other)
           
 void modifyDbRoot(DatabaseImpl db)
          Write the MapLN to disk.
 void modifyDbRoot(DatabaseImpl db, long ifBeforeLsn, boolean mustExist)
          Write a MapLN to the log in order to: - propagate a root change - save per-db utilization information - save database config information.
 void optionalModifyDbRoot(DatabaseImpl db)
          Check deferred write settings before writing the MapLN.
 void readFromLog(ByteBuffer itemBuffer, int entryVersion)
          Initialize this object from the data in itemBuf.
 void rebuildINListMapDb()
          Rebuild the IN list after recovery.
 void releaseDb(DatabaseImpl db)
          Decrements the use count of the given DB, allowing it to be evicted if the use count reaches zero.
 void releaseDbs(Map<DatabaseId,DatabaseImpl> dbCache)
          Calls releaseDb for all DBs in the given map of DatabaseId to DatabaseImpl.
 void removeReplicaDb(Locker locker, String databaseName, DatabaseId checkId, DbOpReplicationContext repContext)
          Replica invocations.
 void renameReplicaDb(Locker locker, String databaseName, String newName, NameLN replicatedLN, DbOpReplicationContext repContext)
          Replica invocations.
(package private)  void setIsConverted()
           
(package private)  void setIsReplicated()
           
 void setLastDbId(int lastReplicatedDbId, int lastLocalDbId)
          Initialize the db ids, from recovery.
 String toString()
           
 long truncate(Locker locker, String databaseName, boolean returnCount)
           
 long truncateReplicaDb(Locker locker, String databaseName, boolean returnCount, NameLN replicatedLN, DbOpReplicationContext repContext)
           
 void updateFromReplay(DatabaseId replayDbId)
           
 boolean verify(VerifyConfig config, PrintStream out)
           
 void writeToLog(ByteBuffer logBuffer)
          This log entry type is configured to perform marshaling (getLogSize and writeToLog) under the write log mutex.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

ID_DB_ID

public static final DatabaseId ID_DB_ID

NAME_DB_ID

public static final DatabaseId NAME_DB_ID

UTILIZATION_DB_NAME

public static final String UTILIZATION_DB_NAME
See Also:
Constant Field Values

REP_GROUP_DB_NAME

public static final String REP_GROUP_DB_NAME
See Also:
Constant Field Values

VLSN_MAP_DB_NAME

public static final String VLSN_MAP_DB_NAME
See Also:
Constant Field Values

NEG_DB_ID_START

public static final int NEG_DB_ID_START
See Also:
Constant Field Values
Constructor Detail

DbTree

public DbTree()
Create a dbTree from the log.


DbTree

public DbTree(EnvironmentImpl env,
              boolean replicationIntended)
       throws DatabaseException
Create a new dbTree for a new environment.

Throws:
DatabaseException
Method Detail

getLastLocalDbId

public int getLastLocalDbId()
The last allocated local and replicated db ids are used for ckpts.


getLastReplicatedDbId

public int getLastReplicatedDbId()

setLastDbId

public void setLastDbId(int lastReplicatedDbId,
                        int lastLocalDbId)
Initialize the db ids, from recovery.


updateFromReplay

public void updateFromReplay(DatabaseId replayDbId)

initExistingEnvironment

void initExistingEnvironment(EnvironmentImpl eImpl)
                       throws DatabaseException
Initialize the db tree during recovery, after instantiating the tree from the log. a. set up references to the environment impl b. check for replication rules.

Throws:
DatabaseException

createDb

public DatabaseImpl createDb(Locker locker,
                             String databaseName,
                             DatabaseConfig dbConfig,
                             Database databaseHandle)
                      throws DatabaseException
Creates a new database object given a database name. Increments the use count of the new DB to prevent it from being evicted. releaseDb should be called when the returned object is no longer used, to allow it to be evicted. See DatabaseImpl.isInUse. [#13415]

Throws:
DatabaseException

createInternalDb

public DatabaseImpl createInternalDb(Locker locker,
                                     String databaseName,
                                     DatabaseConfig dbConfig)
                              throws DatabaseException
Create a database for internal use. It may or may not be replicated. Since DatabaseConfig.replicated is true by default, be sure to set it to false if this is a internal, not replicated database.

Throws:
DatabaseException

createReplicaDb

public DatabaseImpl createReplicaDb(Locker locker,
                                    String databaseName,
                                    DatabaseConfig dbConfig,
                                    NameLN replicatedLN,
                                    ReplicationContext repContext)
                             throws DatabaseException
Create a replicated database on this client node.

Throws:
DatabaseException

optionalModifyDbRoot

public void optionalModifyDbRoot(DatabaseImpl db)
                          throws DatabaseException
Check deferred write settings before writing the MapLN.

Parameters:
db - the database represented by this MapLN
Throws:
DatabaseException

modifyDbRoot

public void modifyDbRoot(DatabaseImpl db)
                  throws DatabaseException
Write the MapLN to disk.

Parameters:
db - the database represented by this MapLN
Throws:
DatabaseException

modifyDbRoot

public void modifyDbRoot(DatabaseImpl db,
                         long ifBeforeLsn,
                         boolean mustExist)
                  throws DatabaseException
Write a MapLN to the log in order to: - propagate a root change - save per-db utilization information - save database config information. Any MapLN writes must be done through this method, in order to ensure that the root latch is taken, and updates to the rootIN are properly safeguarded. See MapN.java for more detail.

Parameters:
db - the database whose root is held by this MapLN
ifBeforeLsn - if argument is not NULL_LSN, only do the write if this MapLN's current LSN is before isBeforeLSN.
mustExist - if true, throw DatabaseException if the DB does not exist; if false, silently do nothing.
Throws:
DatabaseException

dbRename

public void dbRename(Locker locker,
                     String databaseName,
                     String newName)
              throws DatabaseNotFoundException
Stand alone and Master invocations.

Throws:
DatabaseNotFoundException
See Also:
doRenameDb(com.sleepycat.je.txn.Locker, java.lang.String, java.lang.String, com.sleepycat.je.tree.NameLN, com.sleepycat.je.log.DbOpReplicationContext)

renameReplicaDb

public void renameReplicaDb(Locker locker,
                            String databaseName,
                            String newName,
                            NameLN replicatedLN,
                            DbOpReplicationContext repContext)
                     throws DatabaseNotFoundException
Replica invocations.

Throws:
DatabaseNotFoundException
See Also:
doRenameDb(com.sleepycat.je.txn.Locker, java.lang.String, java.lang.String, com.sleepycat.je.tree.NameLN, com.sleepycat.je.log.DbOpReplicationContext)

dbRemove

public void dbRemove(Locker locker,
                     String databaseName,
                     DatabaseId checkId)
              throws DatabaseNotFoundException
Stand alone and Master invocations.

Throws:
DatabaseNotFoundException
See Also:
doRemoveDb(com.sleepycat.je.txn.Locker, java.lang.String, com.sleepycat.je.dbi.DatabaseId, com.sleepycat.je.log.DbOpReplicationContext)

removeReplicaDb

public void removeReplicaDb(Locker locker,
                            String databaseName,
                            DatabaseId checkId,
                            DbOpReplicationContext repContext)
                     throws DatabaseNotFoundException
Replica invocations.

Throws:
DatabaseNotFoundException
See Also:
doRemoveDb(com.sleepycat.je.txn.Locker, java.lang.String, com.sleepycat.je.dbi.DatabaseId, com.sleepycat.je.log.DbOpReplicationContext)

doTruncateDb

public long doTruncateDb(Locker locker,
                         String databaseName,
                         boolean returnCount,
                         NameLN replicatedLN,
                         DbOpReplicationContext repContext)
                  throws DatabaseNotFoundException
To truncate, remove the database named by databaseName and create a new database in its place. Do not evict (do not call CursorImpl.setAllowEviction(true)) during low level DbTree operation. [#15176]

Parameters:
returnCount - if true, must return the count of records in the database, which can be an expensive option.
Throws:
DatabaseNotFoundException - if the operation fails because the given DB name is not found.

truncate

public long truncate(Locker locker,
                     String databaseName,
                     boolean returnCount)
              throws DatabaseNotFoundException
Throws:
DatabaseNotFoundException
See Also:
doTruncateDb(com.sleepycat.je.txn.Locker, java.lang.String, boolean, com.sleepycat.je.tree.NameLN, com.sleepycat.je.log.DbOpReplicationContext)

truncateReplicaDb

public long truncateReplicaDb(Locker locker,
                              String databaseName,
                              boolean returnCount,
                              NameLN replicatedLN,
                              DbOpReplicationContext repContext)
                       throws DatabaseNotFoundException
Throws:
DatabaseNotFoundException
See Also:
doTruncateDb(com.sleepycat.je.txn.Locker, java.lang.String, boolean, com.sleepycat.je.tree.NameLN, com.sleepycat.je.log.DbOpReplicationContext)

deleteMapLN

void deleteMapLN(DatabaseId id)
           throws DatabaseException
Throws:
DatabaseException

getDb

public DatabaseImpl getDb(Locker nameLocker,
                          String databaseName,
                          Database databaseHandle)
                   throws DatabaseException
Get a database object given a database name. Increments the use count of the given DB to prevent it from being evicted. releaseDb should be called when the returned object is no longer used, to allow it to be evicted. See DatabaseImpl.isInUse. [#13415] Do not evict (do not call CursorImpl.setAllowEviction(true)) during low level DbTree operation. [#15176]

Parameters:
nameLocker - is used to access the NameLN. As always, a NullTxn is used to access the MapLN.
databaseName - target database
Returns:
null if database doesn't exist
Throws:
DatabaseException

getDb

public DatabaseImpl getDb(DatabaseId dbId)
                   throws DatabaseException
Get a database object based on an id only. Used by recovery, cleaning and other clients who have an id in hand, and don't have a resident node, to find the matching database for a given log entry.

Throws:
DatabaseException

getDb

public DatabaseImpl getDb(DatabaseId dbId,
                          long lockTimeout)
                   throws DatabaseException
Get a database object based on an id only. Specify the lock timeout to use, or -1 to use the default timeout. A timeout should normally only be specified by daemons with their own timeout configuration. public for unit tests.

Throws:
DatabaseException

getDb

public DatabaseImpl getDb(DatabaseId dbId,
                          long lockTimeout,
                          Map<DatabaseId,DatabaseImpl> dbCache)
                   throws DatabaseException
Get a database object based on an id only, caching the id-db mapping in the given map.

Throws:
DatabaseException

getDb

public DatabaseImpl getDb(DatabaseId dbId,
                          long lockTimeout,
                          String dbNameIfAvailable)
                   throws DatabaseException
Get a database object based on an id only. Specify the lock timeout to use, or -1 to use the default timeout. A timeout should normally only be specified by daemons with their own timeout configuration. public for unit tests. Increments the use count of the given DB to prevent it from being evicted. releaseDb should be called when the returned object is no longer used, to allow it to be evicted. See DatabaseImpl.isInUse. [#13415] Do not evict (do not call CursorImpl.setAllowEviction(true)) during low level DbTree operation. [#15176]

Throws:
DatabaseException

releaseDb

public void releaseDb(DatabaseImpl db)
Decrements the use count of the given DB, allowing it to be evicted if the use count reaches zero. Must be called to release a DatabaseImpl that was returned by a method in this class. See DatabaseImpl.isInUse. [#13415]


releaseDbs

public void releaseDbs(Map<DatabaseId,DatabaseImpl> dbCache)
Calls releaseDb for all DBs in the given map of DatabaseId to DatabaseImpl. See getDb(DatabaseId, long, Map). [#13415]


rebuildINListMapDb

public void rebuildINListMapDb()
                        throws DatabaseException
Rebuild the IN list after recovery.

Throws:
DatabaseException

verify

public boolean verify(VerifyConfig config,
                      PrintStream out)
               throws DatabaseException
Throws:
DatabaseException

getDbName

public String getDbName(DatabaseId id)
                 throws DatabaseException
Return the database name for a given db. Slow, must traverse. Called by Database.getName. Do not evict (do not call CursorImpl.setAllowEviction(true)) during low level DbTree operation. [#15176]

Throws:
DatabaseException

getDbNamesAndIds

public Map<DatabaseId,String> getDbNamesAndIds()
                                        throws DatabaseException
Returns:
a map of database ids to database names (Strings).
Throws:
DatabaseException

getDbNames

public List<String> getDbNames()
                        throws DatabaseException
Returns:
a list of database names held in the environment, as strings.
Throws:
DatabaseException

getInternalNoLookupDbNames

public List<String> getInternalNoLookupDbNames()
Return a list of the names of internally used databases that don't get looked up through the naming tree.


getInternalNoRepDbNames

public List<String> getInternalNoRepDbNames()
Return a list of the names of internally used databases for all environment types.


getInternalRepDbNames

public List<String> getInternalRepDbNames()
Return a list of the names of internally used databases for replication only.


isReservedDbName

public static boolean isReservedDbName(String name)
Returns true if the name is a reserved JE database name.


getHighestLevel

public int getHighestLevel()
                    throws DatabaseException
Returns:
the higest level node in the environment.
Throws:
DatabaseException

getHighestLevel

public int getHighestLevel(DatabaseImpl dbImpl)
                    throws DatabaseException
Returns:
the higest level node for this database.
Throws:
DatabaseException

isReplicated

boolean isReplicated()

setIsReplicated

void setIsReplicated()

isConverted

boolean isConverted()

setIsConverted

void setIsConverted()

getIdDatabaseImpl

public DatabaseImpl getIdDatabaseImpl()

close

public void close()
Release resources and update memory budget. Should only be called when this dbtree is closed and will never be accessed again.


getTreeAdminMemory

long getTreeAdminMemory()

getLogSize

public int getLogSize()
Specified by:
getLogSize in interface Loggable
Returns:
number of bytes used to store this object.
See Also:
Loggable.getLogSize()

writeToLog

public void writeToLog(ByteBuffer logBuffer)
This log entry type is configured to perform marshaling (getLogSize and writeToLog) under the write log mutex. Otherwise, the size could change in between calls to these two methods as the result of utilizaton tracking.

Specified by:
writeToLog in interface Loggable
Parameters:
logBuffer - is the destination buffer
See Also:
Loggable.writeToLog(java.nio.ByteBuffer)

readFromLog

public void readFromLog(ByteBuffer itemBuffer,
                        int entryVersion)
Description copied from interface: Loggable
Initialize this object from the data in itemBuf.

Specified by:
readFromLog in interface Loggable
See Also:
Loggable.readFromLog(java.nio.ByteBuffer, int)

dumpLog

public void dumpLog(StringBuilder sb,
                    boolean verbose)
Description copied from interface: Loggable
Write the object into the string buffer for log dumping. Each object should be dumped without indentation or new lines and should be valid XML.

Specified by:
dumpLog in interface Loggable
Parameters:
sb - destination string buffer
verbose - if true, dump the full, verbose version
See Also:
Loggable.dumpLog(java.lang.StringBuilder, boolean)

getTransactionId

public long getTransactionId()
Specified by:
getTransactionId in interface Loggable
Returns:
the transaction id embedded within this loggable object. Objects that have no transaction id should return 0.
See Also:
Loggable.getTransactionId()

logicalEquals

public boolean logicalEquals(Loggable other)
Specified by:
logicalEquals in interface Loggable
Returns:
true if these two loggable items are logically the same. Used for replication testing.
See Also:
Always return false, this item should never be compared.

dumpString

String dumpString(int nSpaces)

toString

public String toString()
Overrides:
toString in class Object

dump

public void dump()
For debugging.



Copyright (c) 2004-2010 Oracle. All rights reserved.