📄 ramaccessmanager.java
字号:
/* Derby - Class org.apache.derby.impl.store.access.RAMAccessManager Copyright 1997, 2004 The Apache Software Foundation or its licensors, as applicable. 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 org.apache.derby.impl.store.access;import org.apache.derby.iapi.services.cache.Cacheable;import org.apache.derby.iapi.services.cache.CacheableFactory;import org.apache.derby.iapi.services.cache.CacheFactory;import org.apache.derby.iapi.services.cache.CacheManager;import org.apache.derby.iapi.services.context.ContextManager;import org.apache.derby.iapi.services.context.ContextService;import org.apache.derby.iapi.services.daemon.Serviceable;import org.apache.derby.iapi.services.locks.LockFactory;import org.apache.derby.iapi.services.monitor.ModuleControl;import org.apache.derby.iapi.services.monitor.Monitor;import org.apache.derby.iapi.services.property.PropertySetCallback;import org.apache.derby.iapi.services.sanity.SanityManager;import org.apache.derby.iapi.services.io.FormatIdUtil;import org.apache.derby.iapi.error.StandardException;import org.apache.derby.iapi.store.access.conglomerate.Conglomerate;import org.apache.derby.iapi.store.access.conglomerate.ConglomerateFactory;import org.apache.derby.iapi.store.access.conglomerate.MethodFactory;import org.apache.derby.iapi.store.access.conglomerate.TransactionManager;import org.apache.derby.iapi.services.property.PropertyUtil;import org.apache.derby.iapi.store.access.AccessFactory;import org.apache.derby.iapi.services.property.PropertyFactory;import org.apache.derby.iapi.store.access.AccessFactoryGlobals;import org.apache.derby.iapi.store.access.TransactionController;import org.apache.derby.iapi.store.access.TransactionInfo;import org.apache.derby.iapi.store.raw.ContainerHandle;import org.apache.derby.iapi.store.raw.ContainerKey;import org.apache.derby.iapi.store.raw.LockingPolicy;import org.apache.derby.iapi.store.raw.RawStoreFactory;import org.apache.derby.iapi.store.raw.Transaction;import org.apache.derby.catalog.UUID;import org.apache.derby.iapi.services.io.FormatableHashtable;import org.apache.derby.iapi.reference.SQLState;import org.apache.derby.iapi.reference.Attribute;import java.util.Dictionary;import java.util.Enumeration;import java.util.Hashtable;import java.util.Properties;import java.io.File;import java.io.Serializable;public abstract class RAMAccessManager implements AccessFactory, CacheableFactory, ModuleControl, PropertySetCallback{ /************************************************************************** * Fields of the class ************************************************************************** */ /** The raw store that this access manager uses. **/ private RawStoreFactory rawstore; /** Hash table on primary implementation type. **/ private Hashtable implhash; /** Hash table on primary format. **/ private Hashtable formathash; /** Service properties. These are supplied from ModuleControl.boot(), and ultimately come from the service.properties file. By convention, these properties are passed down to all modules booted by this one. If this module needs to pass specific instructions to its sub-modules, it should create a new Properties object with serviceProperties as its default (so that the rest of the modules that are looking at it don't see the properties that this module needs to add). **/ private Properties serviceProperties; /** * Default locking policy for the entire system. **/ LockingPolicy system_default_locking_policy; /** The object providing the properties like behaviour that is transactional. */ private PropertyConglomerate xactProperties; private PropertyFactory pf; protected LockingPolicy table_level_policy[]; protected LockingPolicy record_level_policy[]; /** * A map of the implementation specific id to conglomerate object. * <p> * A map of the implementation specific id to conglomerate object. * The id is encoded into the conglomerate number, and then used to * pick the right implementation of the conglomerate. It is then * up to the conglomerate implementation to retrieve it's stored * representation from disk. * * An internal mapping of the encoding of conglomerate identity in the * conglomerate number to the actual conglomerate implementation. Encoding * this means that we can't dynamically add conglomerate implementations * into the system, so when we want to do that this mapping will have to * be more dynamic - but for now store knows exactly what implementations * there are. **/ protected ConglomerateFactory conglom_map[]; /** * Cache of Conglomerate objects, keyed by conglom id. Used to speed up * subsquent open of conglomerates, first open will need to call the * conglomerate to read and return it's description. **/ private CacheManager conglom_cache; /************************************************************************** * Constructors for This class: ************************************************************************** */ public RAMAccessManager() { // Intialize the hash tables that hold the access methods that // this access manager knows about. implhash = new Hashtable(); formathash = new Hashtable(); } /************************************************************************** * Private/Protected methods of This class: ************************************************************************** */ /** * Return the default locking policy for this access manager. * * @return the default locking policy for this accessmanager. **/ protected LockingPolicy getDefaultLockingPolicy() { return(system_default_locking_policy); } RawStoreFactory getRawStore() { return rawstore; } PropertyConglomerate getTransactionalProperties() { return xactProperties; } private void boot_load_conglom_map() throws StandardException { // System.out.println("before new code."); conglom_map = new ConglomerateFactory[2]; // Find the appropriate factory for the desired implementation. MethodFactory mfactory = findMethodFactoryByImpl("heap"); if (mfactory == null || !(mfactory instanceof ConglomerateFactory)) { throw StandardException.newException( SQLState.AM_NO_SUCH_CONGLOMERATE_TYPE, "heap"); } conglom_map[ConglomerateFactory.HEAP_FACTORY_ID] = (ConglomerateFactory) mfactory; // Find the appropriate factory for the desired implementation. mfactory = findMethodFactoryByImpl("BTREE"); if (mfactory == null || !(mfactory instanceof ConglomerateFactory)) { throw StandardException.newException( SQLState.AM_NO_SUCH_CONGLOMERATE_TYPE, "BTREE"); } conglom_map[ConglomerateFactory.BTREE_FACTORY_ID] = (ConglomerateFactory) mfactory; // System.out.println("conglom_map[0] = " + conglom_map[0]); // System.out.println("conglom_map[1] = " + conglom_map[1]); } /*************************************************************************** ** Abstract Methods of RAMAccessManager, interfaces that control locking ** level of the system. **************************************************************************** */ /** * Return the locking level of the system. * <p> * This routine controls the lowest level of locking enabled for all locks * for all tables accessed through this accessmanager. The concrete * implementation may set this value always to table level locking for * a client configuration, or it may set it to row level locking for a * server configuration. * <p> * If TransactionController.MODE_RECORD is returned table may either be * locked at table or row locking depending on the type of access expected * (ie. level 3 will require table locking for heap scans.) * * @return TransactionController.MODE_TABLE if only table locking allowed, * else returns TransactionController.MODE_RECORD. * **/ abstract protected int getSystemLockLevel(); /** * Query property system to get the System lock level. * <p> * This routine will be called during boot after access has booted far * enough, to allow access to the property conglomerate. This routine * will call the property system and set the value to be returned by * getSystemLockLevel(). * <p> * * @return The identifier to be used to open the conglomerate later. * * @exception StandardException Standard exception policy. **/ abstract protected void bootLookupSystemLockLevel( TransactionController tc) throws StandardException; /************************************************************************** * Routines to map to/from conglomid/containerid: ************************************************************************** */ private long conglom_nextid = 0; /** * Return next conglomid to try to add the container with. * <p> * The conglomerate number has 2 parts. The low 4 bits are used to * encode the factory which "owns" the conglomerate. The high 60 bits * are used as a normal unique id mechanism. * <p> * So for example if the next id to assign is 0x54 the following will * be the conglomid: * if a HEAP (factory 0) - 0x540 * if a BTREE (factory 1) - 0x541 * * And the next id assigned will be: * if a HEAP (factory 0) - 0x550 * if a BTREE (factory 1) - 0x551 * * @param factory_type factory id as gotten from getConglomerateFactoryId() * * @return The identifier to be used to open the conglomerate later. * * @exception StandardException Standard exception policy. **/ protected long getNextConglomId(int factory_type) throws StandardException { long conglomid; if (SanityManager.DEBUG) { // current code depends on this range, if we ever need to expand the // range we can claim bits from the high order of the long. SanityManager.ASSERT(factory_type >= 0x00 && factory_type <= 0x0f); } synchronized (conglom_cache) { if (conglom_nextid == 0) { // shift out the factory id and then add 1. conglom_nextid = (rawstore.getMaxContainerId() >> 4) + 1; } conglomid = conglom_nextid++; } // shift in the factory id and then return the conglomid. return((conglomid << 4) | factory_type); } /** * Bump the conglomid. * <p> * For some reason we have found that the give conglomid already exists * in the directory so just bump the next conglomid to greater than this * one. The algorithm to store and retrieve the last conglomid is not * transactional as we don't want to pay the overhead for such an algorithm * on every ddl statement - so it is possible to "lose" an update to the * counter if we crash at an inopportune moment. In general the upper * level store code will just handle the error from addContainer which * says there already exists a conglom with that id, update the next * conglomid and then try again. * <p> * * @param conglomid The conglomid which already exists. * * @exception StandardException Standard exception policy. **/ // currently not used, but this is one idea on how to handle // non-transactional update of the nextid field, just handle the error // if we try to create a conglom and find the container already exists. /* private void handleConglomidExists( long conglomid) throws StandardException { synchronized (conglom_cache) { conglom_nextid = ((conglomid >> 4) + 1); } } */ /** * Given a conglomid, return the factory which "owns" it. * <p> * A simple lookup on the boot time built table which maps the low order * 4 bits into which factory owns the conglomerate. * <p> * * @param conglom_id The conglomerate id of the conglomerate to look up. * * @return The ConglomerateFactory which "owns" this conglomerate. * * @exception StandardException Standard exception policy. **/ private ConglomerateFactory getFactoryFromConglomId( long conglom_id) throws StandardException { try { return(conglom_map[((int) (0x0f & conglom_id))]); } catch (java.lang.ArrayIndexOutOfBoundsException e) { // just in case language passes in a bad factory id. throw StandardException.newException( SQLState.STORE_CONGLOMERATE_DOES_NOT_EXIST, new Long(conglom_id)); } } /************************************************************************** * Conglomerate Cache routines: ************************************************************************** */ /** * ACCESSMANAGER CONGLOMERATE CACHE - * <p> * Every conglomerate in the system is described by an object which * implements Conglomerate. This object basically contains the parameters * which describe the metadata about the conglomerate that store needs * to know - like types of columns, number of keys, number of columns, ... * <p> * It is up to each conglomerate to maintain it's own description, and * it's factory must be able to read this info from disk and return it * from the ConglomerateFactory.readConglomerate() interface. * <p> * This cache simply maintains an in memory copy of these conglomerate
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -