Package com.mobixess.jodb.core.index

Source Code of com.mobixess.jodb.core.index.JODBIndexingRootAgent

/*
Copyright (C) 2007  Mobixess Inc. http://www.java-objects-database.com

This file is part of the JODB (Java Objects Database) open source project.

JODB is free software; you can redistribute it and/or modify it under
the terms of version 2 of the GNU General Public License as published
by the Free Software Foundation.

JODB is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
package com.mobixess.jodb.core.index;

import java.io.IOException;
import java.lang.reflect.Field;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Vector;

import com.mobixess.jodb.core.IllegalClassTypeException;
import com.mobixess.jodb.core.agent.JODBAgent;
import com.mobixess.jodb.core.io.IOBase;
import com.mobixess.jodb.core.io.JODBOperationContext;
import com.mobixess.jodb.core.io.ObjectDataContainer;
import com.mobixess.jodb.core.io.ObjectDataContainer.FIELD_CATEGORIES;
import com.mobixess.jodb.core.io.ObjectDataContainer.FieldRecord;
import com.mobixess.jodb.core.io.ObjectDataContainer.FieldsIterator;
import com.mobixess.jodb.core.transaction.TransactionContainer;
import com.mobixess.jodb.core.transaction.TransactionUtils;
import com.mobixess.jodb.core.transaction.TransactionUtils.DataContainersCache;
import com.mobixess.jodb.util.PrimitiveJavaTypesUtil;

public class JODBIndexingRootAgent extends JODBAgent {

    private final static int DEFAULT_CAPACITY = 30;
    private final static int DEFAULT_INCREMENT = 30;
   
    private JODBIndexingAgent[] _agents;
   
    private short _totalAgents;   
    private int _capacityIncrement;
    private long _version;
   
    public JODBIndexingRootAgent() {
        this(DEFAULT_CAPACITY, DEFAULT_INCREMENT);
    }
   
    public JODBIndexingRootAgent(int initialCapacity, int capacityIncrement) {
        _agents = new JODBIndexingAgent[initialCapacity];
        _capacityIncrement = capacityIncrement;
    }
   
    public void setVersion(long version) {
        _version = version;
    }
   
    public long getVersion() {
        return _version;
    }
   
    public synchronized JODBIndexingAgent enableIndex(Field field, JODBOperationContext context) throws IOException{
        TransactionContainer transactionContainer = context.getTransactionContainer();
        transactionContainer.enableAgentMode();
        try{
            JODBIndexingAgent agent = addAgent(field, context);
            IOBase base = context.getBase();
            int classId = base.getOrSetClassTypeSubstitutionID(field.getDeclaringClass());
            int fieldId = base.getOrSetFieldSubstitutionID(field);
            long[] allOffsets = base.getForAllObjects(context.getIoTicket());
            DataContainersCache dataContainersCache = TransactionUtils.getObjectDataContainerCache();
            ObjectDataContainer dataContainer = dataContainersCache.pullObjectDataContainer();
            try{
                for (int i = 0; i < allOffsets.length; i++) {
                    processIndexForObjectId(allOffsets[i], classId, fieldId, field.getType(), dataContainer, agent, context);
                    dataContainer.reset();
                }
                try {
                    transactionContainer.set(agent, Integer.MAX_VALUE);
                } catch (IllegalClassTypeException e) {
                    e.printStackTrace();
                }
            }finally{
                dataContainersCache.pushObjectDataContainer(dataContainer);
            }
           
            return agent;
        }finally{
            transactionContainer.disableAgentMode();
        }
    }
   
    private void processIndexForObjectId(long objectOffset, int classId, int fieldId, Class fieldType, ObjectDataContainer dataContainer, JODBIndexingAgent agent, JODBOperationContext context) throws IOException{
        FieldsIterator fieldsIterator = dataContainer.readObject(context, objectOffset, true);
        if(fieldsIterator!=null){
            if(dataContainer.getOriginalClassType()!=classId){
                return;
            }
            if(dataContainer.getOriginalClassType() != dataContainer.getTranslatedClassType()){
                throw new IllegalArgumentException("No indexing for translated classes");
            }
            FieldRecord fieldRecord = dataContainer.getRecordCache();
            IOBase base = context.getBase();
            while (fieldsIterator.hasNext()) {
                fieldsIterator.next(fieldRecord, base,false);
                if(fieldRecord._category != FIELD_CATEGORIES.PRIMITIVE){//TODO optimize to skip none primitive fields
                    continue;
                }
                if(fieldRecord._fieldID == fieldId){
                    agent.insertIndex(objectOffset, fieldRecord._primitiveRawDataBuffer, context);
                    return;
                }
            }
            //add field as having default value
            ByteBuffer defaultValue = PrimitiveJavaTypesUtil.getDefaultValueAsByteBuffer(fieldType);
            agent.insertIndex(objectOffset, defaultValue, context);
        }
    }
   
    public synchronized void getAgentsForClassId(Vector<IndexingRecord> agentsBuffer, int classTypeId){
        for (int i = 0; i < _totalAgents; i++) {
            if(_agents[i].getClassId() == classTypeId){
                IndexingRecord indexingRecord = TransactionUtils.getObjectDataContainerCache().pullIndexRecord();
                indexingRecord.setIndexingAgent(_agents[i]);
                agentsBuffer.add(indexingRecord);
            }
        }
    }
   
    private synchronized JODBIndexingAgent addAgent(Field field, JODBOperationContext context) throws IOException{
        TransactionContainer transactionContainer = context.getTransactionContainer();
        transactionContainer.enableAgentMode();
        try{
            int fieldId = context.getBase().getOrSetFieldSubstitutionID(field);
            for (int i = 0; i < _totalAgents; i++) {
                if(_agents[i].getFieldId() == fieldId){
                    return _agents[i];
                }
            }
            _totalAgents++;
            _agents = ensurePersistentArrayCapacity(_agents, _totalAgents, transactionContainer, _capacityIncrement);
            _agents[_totalAgents-1] = new JODBIndexingAgent(field,context);
            try {
                transactionContainer.set(this, Integer.MAX_VALUE);
            } catch (IllegalClassTypeException e) {
                // TODO log
                e.printStackTrace();
            }
            return _agents[_totalAgents-1];
        }finally{
            transactionContainer.disableAgentMode();
        }
    }
   
    public JODBIndexingAgent getIndexingAgent(Field field, IOBase base){
        int fieldId = base.getFieldSubstitutionID(field);
        return getIndexingAgent(fieldId, base);
    }
   
    public JODBIndexingAgent getIndexingAgent(int fieldId, IOBase base){
        for (int i = 0; i < _totalAgents; i++) {
            if(_agents[i].getFieldId() == fieldId){
                return _agents[i];
            }
        }
        return null;
    }
   
    public synchronized void removeAgent(Field field, JODBOperationContext context){
        int fieldId = context.getBase().getOrSetFieldSubstitutionID(field);
        for (int i = 0; i < _totalAgents; i++) {
            if(_agents[i].getFieldId() == fieldId){
                TransactionContainer transactionContainer = context.getTransactionContainer();
                try {
                    transactionContainer.delete(_agents[i], Integer.MAX_VALUE);
                } catch (IllegalClassTypeException e) {
                    // TODO log
                    e.printStackTrace();
                }
                if(i < _totalAgents-1){
                    System.arraycopy(_agents, i+1, _agents, i, _totalAgents - i);
                    _agents[_totalAgents-1] = null;
                }
                _totalAgents--;
                try {
                    transactionContainer.enableAgentMode();
                    transactionContainer.set(_agents, 1);
                } catch (IllegalClassTypeException e) {
                    // TODO log
                    e.printStackTrace();
                } finally{
                    transactionContainer.disableAgentMode();
                }
                break;
            }
        }
    }
   
   
    public static <T> T[] ensurePersistentArrayCapacity(T[] initialArray, int size, TransactionContainer container, int capacityIncrement){
        if(size >= initialArray.length){
            @SuppressWarnings("unchecked")
            T[] newAgentsArray = (T[])java.lang.reflect.Array.newInstance(initialArray.getClass().getComponentType(), size+capacityIncrement);
            System.arraycopy(initialArray, 0, newAgentsArray, 0, initialArray.length);
            Arrays.fill(initialArray, null);
            try {
                container.delete(initialArray, 1);
            } catch (IllegalClassTypeException e) {
                //TODO log
                e.printStackTrace();
            }
            initialArray = newAgentsArray;
        }
        return initialArray;
    }
}
TOP

Related Classes of com.mobixess.jodb.core.index.JODBIndexingRootAgent

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.