Package com.mobixess.jodb.core.io

Examples of com.mobixess.jodb.core.io.IRandomAccessDataBuffer


        }
    };
   
    public static boolean compareToPersistentValues(JODBSession session, Field[] fields, int[] fieldsIDs, Object currentObject, IOTicket ioTicket, ObjectDataContainer headerData ) throws IOException{
        boolean[] processedFields = new boolean[fieldsIDs.length];
        IRandomAccessDataBuffer in = ioTicket.getRandomAccessBuffer();
        short classNameIDs = in.readShort();
        for (int i = 0; i < classNameIDs; i++) {
            in.readShort();
        }
       
        //null fields no longer persisted
//        if(headerData.hasNullFields()){
//            int nullFieldsTotal = in.readShort()&0xffff;
//            for (int i = 0; i < nullFieldsTotal; i++) {
//                int id = in.readShort()&0xffff;
//                int index = ArrayUtils.indexOf(fieldsIDs, id);
//                if(index == -1){
//                    continue;
//                }
//                Field field = fields[index];
//                try {
//                    if(field.get(currentObject)!=null){//TODO may need additional check if object is in transaction, rare case though
//                        return false;
//                    }
//                } catch (Exception e) {
//                    e.printStackTrace();
//                    throw new IOException(e.getMessage());
//                }
//                processedFields[index] = true;
//            }
//        }

        if(headerData.hasDirectlyAddressedFields()){
            boolean result = verifyLinks(session, false, fields, fieldsIDs, processedFields, currentObject, ioTicket);
            if(!result){
                return false;
            }
        }
       
        if(headerData.hasRelativelyAddressedFields()){
            boolean result = verifyLinks(session, true, fields, fieldsIDs, processedFields, currentObject, ioTicket);
            if(!result){
                return false;
            }
        }
       
        //long endOffset = headerData.getOffset() + headerData.getTotalLength();
       
        if (headerData.hasPrimitiveFields()) {
            int total = in.readShort()&0xFFFF;
            for (int i = 0; i < total; i++) {
                int id = in.readShort() & 0xffff;
                int index = ArrayUtils.indexOf(fieldsIDs, id);
                Field field = fields[index];
                if (index == -1) {
                    Utils.skipPrimitive(field, ioTicket.getRandomAccessBuffer());
                    continue;
View Full Code Here


        }
        dataOutput.writeLong(offset);
    }
   
    private static boolean verifyLinks(JODBSession session, boolean isRelativeAddr, Field[] fields, int[] fieldsIDs, boolean[] processedFields, Object currentObject, IOTicket ioTicket) throws IOException{
        IRandomAccessDataBuffer in = ioTicket.getRandomAccessBuffer();
        int directlyAddressedFieldsTotal = in.readShort()&0xffff;
        for (int i = 0; i < directlyAddressedFieldsTotal; i++) {
            int id = in.readShort()&0xffff;
            long offset;
            if(isRelativeAddr){
                offset = in.readInt()+ in.getCursorOffset();
            }else{
                offset = in.readLong();
            }
            int index = ArrayUtils.indexOf(fieldsIDs, id);
            if(index == -1){
                continue;
            }
View Full Code Here

                }
            }           
            return offset;
        }
       
        IRandomAccessDataBuffer transactionFile = tContainer.getTransactionNewDataFile();
        transactionFile.resetToEnd();
       
        Vector<ObjectFieldRecord> fieldsWithAbsoluteAddr = new Vector<ObjectFieldRecord>();
        Vector<ObjectFieldRecord> fieldsWithRelativeAddr = new Vector<ObjectFieldRecord>();
        Vector<Field> primitiveFields = new Vector<Field>();
       
        if(!classDescr.isArray()){
            classifyFields(objectToPersist, classDescr, transactionObjects, fieldsWithAbsoluteAddr, fieldsWithRelativeAddr, primitiveFields);
        }
       
       
        long objectIDOffset = transactionFile.getCursorOffset();
       
        tHandle.setTransactionOffset(objectIDOffset);

        if(JODBConfig.DEBUG){
            _logger.info(" >>> Transaction: Object "+rootObject.getClass()+" "+rootObject+" start offset ="+objectIDOffset);
        }
       
        boolean translated = rootObject!=objectToPersist;
        byte arrayElementSize = 0;
        long lengthEstimate;
        if(!classDescr.isArray()){
            lengthEstimate = estimateObjectLength(tHandle, fieldsWithAbsoluteAddr.size(), fieldsWithRelativeAddr.size(), classDescr, translated);
        }else{
            ByteHolder byteHolder = new ByteHolder();
            lengthEstimate = estimateArrayObjectLength(context, tHandle, objectToPersist, classDescr, byteHolder, translated);
            arrayElementSize = byteHolder._value;
        }
       
        int objId = composeEntryID( JODBIOBase.ENTRY_OBJECT_ID, lengthEstimate);
        int objIdWithRedirectionBit = tHandle.isNewObject()? objId : JODBIOBase.addRedirectedObjectModifier(objId);
        transactionFile.writeShort(objIdWithRedirectionBit);
        writeEntryLenForID(objId,0,transactionFile);//reserve space for length
       
        long objectBodyOffset = transactionFile.getCursorOffset();
       
//        if(JODBConfig.DEBUG){
//            _logger.info("Transaction: Object "+rootObject.getClass()+" "+rootObject+" header len ="+headerLen);
//        }
       
        int primaryMask = formPrimaryObjectMask(0, fieldsWithAbsoluteAddr.size()>0, fieldsWithRelativeAddr.size()>0, primitiveFields.size()>0, translated, tHandle, classDescr);;
       
        transactionFile.writeByte(primaryMask);
       
        int secondaryMask = formSecondaryObjectMask(0, tHandle);
       
        transactionFile.writeByte(secondaryMask);
       
        short newCyclicCounter =  (short) (tHandle.getCyclicalVersionCounter()+1);
       
        if(newCyclicCounter == 256){
            newCyclicCounter = 0;
        }
        tHandle.setCyclicalVersionCounter(newCyclicCounter);
       
        transactionFile.writeByte(newCyclicCounter);
       
        tHandle.setTranslatedObjectDataMask((byte) primaryMask);
       
        //
        if(tHandle.generateUID()){
            Random random = new Random();
            transactionFile.writeLong(random.nextLong());
        }
        long time = System.currentTimeMillis();
        if(tHandle.generateCreationTS()){
            transactionFile.writeLong(time);
        }
        if(tHandle.generateModificationTS()){
            transactionFile.writeLong(time);
        }
       
        //
        transactionFile.writeShort(rootObjectClassID);
       
        if(translated){
            int translatedObjectClassID = base.getOrSetClassTypeSubstitutionID(classDescr.getTypes()[0]);// base.getOrSetClassTypeSubstitutionID( objectToPersist.getClass().getName());
            transactionFile.writeShort(translatedObjectClassID);
        }
       
//        transactionFile.writeShort(classTypes.length);
//       
//        for (int i = 0; i < classTypes.length; i++) {
//            int id = base.getOrSetClassTypeSubstitutionID(classTypes[i]);
//            transactionFile.writeShort(id);
//        }

        if(fieldsWithAbsoluteAddr.size()>0){//with absolute offsets
            transactionFile.writeShort(fieldsWithAbsoluteAddr.size());
            for (int i = 0; i < fieldsWithAbsoluteAddr.size(); i++) {//writing links of unchanged objects
                ObjectFieldRecord next = fieldsWithAbsoluteAddr.elementAt(i);
                int id = base.getOrSetFieldSubstitutionID(next._field);
                transactionFile.writeShort(id);
                TransactionHandle valueHandle = transactionObjects.get(next._value);
                transactionFile.writeLong(valueHandle.getHandle().getObjectEntryOffset());
            }
        }
       
        long objectsWithRelativeAddrStartOffsetShift = -1;
        if(fieldsWithRelativeAddr.size()>0){//with relative offsets
            transactionFile.writeShort(fieldsWithRelativeAddr.size());
            objectsWithRelativeAddrStartOffsetShift = transactionFile.getCursorOffset() - objectIDOffset;
            transactionFile.setLength(transactionFile.length()+ fieldsWithRelativeAddr.size()*(2+4));
            transactionFile.seek(transactionFile.length());
        }
       
        if(primitiveFields.size()>0){
            transactionFile.writeShort(primitiveFields.size());
        }
        for (int i = 0; i < primitiveFields.size(); i++) {
            Field next = primitiveFields.elementAt(i);
            int id = base.getOrSetFieldSubstitutionID(next);
            transactionFile.writeShort(id);
            IndexingRecord record = IndexingRecord.findIndexingRecord(id, indexes);
            if(record!=null){
                //ByteBuffer currentlyPersistedValue = record.getPersistedDataBuffer();
                ByteBuffer pendingValue = record.getPendingDataBuffer();
                pendingValue.clear();
                PrimitiveJavaTypesUtil.primitiveToByteBuffer(objectToPersist, next, pendingValue);
                pendingValue.flip();
                transactionFile.getChannel().write(pendingValue);
                pendingValue.rewind();
            }else {
                try {
                    Utils.writePrimitive(objectToPersist, next,transactionFile);
                } catch (Exception e) {
                    throw new JodbIOException(e);
                }
            }           
        }
       
        long arrayDataShift = 0;
        if(classDescr.isArray()){
            int arrayLength = Array.getLength(objectToPersist);
            transactionFile.writeInt(arrayLength);
            transactionFile.writeByte(arrayElementSize);//write length of each element in array
            arrayDataShift = transactionFile.getCursorOffset() - objectIDOffset;
            boolean primitive = classDescr.isPrimitiveArray();
            if(primitive){//completely write primitive array
                try {
                    Utils.writePrimitiveArray(objectToPersist, classDescr.getArrayType(), 0, arrayLength, transactionFile);
                } catch (Exception e) {
                    _logger.log(Level.SEVERE,"",e);
                    throw new JodbIOException(e);
                }
            }else{//reserve space for references
                long spaceToReserve = arrayElementSize*arrayLength;
                long slotMasksTotal = arrayLength/8;
                if( slotMasksTotal*8 != arrayLength){
                    slotMasksTotal++;//trailing mask entry for slot <8
                }
                spaceToReserve+=slotMasksTotal;
                if(transactionFile.getCursorOffset() + spaceToReserve > transactionFile.length()  ){
                    transactionFile.setLength(transactionFile.getCursorOffset() + spaceToReserve );
                }
                transactionFile.skip(spaceToReserve);
               
            }
        }
       
        if(JODBConfig.DEBUG){
            _logger.info(" <<< Transaction: Object "+rootObject.getClass()+" "+rootObject+" end offset ="+transactionFile.getCursorOffset());
        }
       
        long objectEndOffset = transactionFile.getCursorOffset();
        long objectBodyLength = objectEndOffset - objectBodyOffset;
        if(lengthEstimate < objectBodyLength){
            throw new JodbIOException("Object length estimate error");
        }
        //long targetObjectBodyLength = objectBodyLength;
       
        if(!tHandle.isNewObject()){
            DataContainersCache dataContainersCache = TransactionUtils.getObjectDataContainerCache();
            ObjectDataContainer existingObjectHeaderData =  dataContainersCache.pullObjectDataContainer();// tContainer.getTempObjectDataContainer();

            //ioTicket.getRandomAccessBuffer().seek(tHandle.getHandle().getObjectEntryOffset());
            //JODBIOUtils.readObjectHeader(ioTicket, existingObjectHeaderData, false);
            existingObjectHeaderData.readHeader(ioTicket.getRandomAccessBuffer(),tHandle.getHandle().getObjectEntryOffset(), false);
            tHandle.setTransactionOffset(existingObjectHeaderData.getOffset());//JODBIOUtils.addAbsoluteOffsetIdentifierBit(existingObjectHeaderData.getOffset()));//if object already existed than alvays point to initial object position
            long redirectorOffset = existingObjectHeaderData.isRedirection()?existingObjectHeaderData.getOffset():-1;
            if(objectBodyLength > existingObjectHeaderData.getBodyLength() || fieldsWithRelativeAddr.size() > 0 ){
                if( existingObjectHeaderData.isRedirection() ){
                    //redirection entry space is too small, let see what is under redirection offset
                    //ioTicket.getRandomAccessBuffer().seek(existingObjectHeaderData.getRedirectionOffset());
                    long existingObjectRedirectionOffset = existingObjectHeaderData.getRedirectionOffset();
                    existingObjectHeaderData.reset();
                    existingObjectHeaderData.readHeader(ioTicket.getRandomAccessBuffer(), existingObjectRedirectionOffset, true);
                    //JODBIOUtils.readObjectHeader(ioTicket, existingObjectHeaderData, true);
                }
            }

            if(objectBodyLength <= existingObjectHeaderData.getBodyLength() && fieldsWithRelativeAddr.size() == 0){
                boolean isRedirection = existingObjectHeaderData.isRedirection();
                long redirectionOffset = existingObjectHeaderData.getRedirectionOffset();
                //long targetObjectBodyLength = existingObjectHeaderData.getBodyLength();//length for new object's header
               
                //object id(length bits) may change as we fit to maybe bigger space
                objId = JODBIOBase.ENTRY_OBJECT_ID | existingObjectHeaderData.getLengthModifierFromID();// composeEntryID( JODBIOBase.ENTRY_OBJECT_ID, targetObjectBodyLength);
               
                if(existingObjectHeaderData.isRedirectedObject()){
                    objIdWithRedirectionBit = JODBIOBase.addRedirectedObjectModifier(objId);//this is redirected entry
                }else{
                    objIdWithRedirectionBit = objId;
                }
               
                if( isRedirection ){//if we fit into redirection record than delete record under redirection offset
                    deleteObject(ioTicket, session, redirectionOffset, tContainer);//delete/backup record under redirection offset
                }
               
               
                //object can fit to old spot, write it to replacements file insteard of transaction file
                IRandomAccessDataBuffer replacementsFile = tContainer.getTransactionReplacementsDataFile();
                replacementsFile.resetToEnd();
                replacementsFile.writeByte(TRANSACTION_REPLACEMENT_ENTRY_TYPE_STATIC);
                replacementsFile.writeLong(existingObjectHeaderData.getOffset());
                long replacementLengthEntryOffset = replacementsFile.getCursorOffset();
                replacementsFile.writeLong(0);//reserve space for replacement length entry. //TODO skip faster?
                long newObjectIDOffset = replacementsFile.getCursorOffset();
               
                replacementsFile.writeShort(objIdWithRedirectionBit);//write new ID to replacements file
                writeEntryLenForID(objId,objectBodyLength,replacementsFile);//write length of replacements file, could be bigger than actual object's data occupies
               
                long newObjectBodyOffset = replacementsFile.getCursorOffset();
                //return to write actual length of replacement entry
                replacementsFile.seek(replacementLengthEntryOffset);
                replacementsFile.writeLong(newObjectBodyOffset-newObjectIDOffset+objectBodyLength);
                replacementsFile.seek(newObjectBodyOffset);//back to the header end
               
                transactionFile.transferTo(objectBodyOffset, objectBodyLength, replacementsFile.getChannel());
                transactionFile.seek(objectIDOffset);//return position in transaction file to the start of object(like it wasn't here)
                transactionFile.setLength(objectIDOffset);//truncate "new data" file
                objectIDOffset = newObjectIDOffset;//this now offset in replacements file
                objectBodyOffset = newObjectBodyOffset;
                objectBodyLength = existingObjectHeaderData.getBodyLength();//length for new object
                transactionFile = replacementsFile;
                replacementsFile.resetToEnd();//replacements file to the end
                objectEndOffset = replacementsFile.getCursorOffset();
            }else{
                if(redirectorOffset!=-1){
                    //this is record under redirection offset
                    deleteObject(ioTicket, session, existingObjectHeaderData.getOffset(), tContainer);
                }
                IRandomAccessDataBuffer replacementsFile = tContainer.getTransactionReplacementsDataFile();
                long offset = tHandle.getHandle().getObjectEntryOffset();//offset of record that will be replaced with redirector
                //backupObject(ioTicket, offset, tContainer);
                //write redirector entry with relative offset
                replacementsFile.writeByte(TRANSACTION_REPLACEMENT_ENTRY_TYPE_REDIRECTOR);
                replacementsFile.writeLong(offset);
                replacementsFile.writeLong(objectIDOffset);//relative offset in new data transaction file
            }
            dataContainersCache.pushObjectDataContainer(existingObjectHeaderData);
        }
       
        for (int i = 0; i < fieldsWithRelativeAddr.size(); i++) {
View Full Code Here

        deleteObject(ioTicket, session, persistentObjectOffset, tContainer);
    }
   
    private static void deleteObject(IOTicket ioTicket, JODBSession session, long persistentObjectOffset, TransactionContainer tContainer) throws IOException{
        //ioTicket.getRandomAccessBuffer().seek(persistentObjectOffset);
        IRandomAccessDataBuffer replacementsFile =  tContainer.getTransactionReplacementsDataFile();
        DataContainersCache dataContainersCache = TransactionUtils.getObjectDataContainerCache();
        ObjectDataContainer container = dataContainersCache.pullObjectDataContainer();
        //JODBIOUtils.readObjectHeader(ioTicket, container, false);
        container.readHeader(ioTicket.getRandomAccessBuffer(),persistentObjectOffset, false);
        replacementsFile.writeByte(TRANSACTION_REPLACEMENT_ENTRY_TYPE_STATIC);
        replacementsFile.writeLong(persistentObjectOffset);//write offset of object to replace
        replacementsFile.writeLong(0);//reserving space for entry's length
        long entryOffsetStart = replacementsFile.getCursorOffset();
        TransactionUtils.writeEmptyObjectEntry(replacementsFile , container.getBodyLength());
        long entryEnd = replacementsFile.getCursorOffset();
        long entryLength = entryEnd - entryOffsetStart;
        replacementsFile.seek(entryOffsetStart-8);//go back to entry's length
        replacementsFile.writeLong(entryLength);
        if(container.isRedirection()){
            persistentObjectOffset = container.getOffset();
            deleteObject(ioTicket, session, persistentObjectOffset, tContainer);
        }
        dataContainersCache.pushObjectDataContainer(container);
        replacementsFile.seek(entryEnd);
    }
View Full Code Here

                listener = _transactionBufferListenerSERVER_TEMP;
                break;
            default:
                throw new RuntimeException();
            }
            IRandomAccessDataBuffer result = new RandomAccessTestTransactionBuffer(name,listener,write);
            _cache.put(result,null);
            return result;
        }
View Full Code Here

       
        public void printCache(){
            System.err.println("TestBufferFactory **********START************");
            Iterator<IRandomAccessDataBuffer> iterator = _cache.keySet().iterator();
            while (iterator.hasNext()) {
                IRandomAccessDataBuffer element = (IRandomAccessDataBuffer) iterator.next();
                System.err.println("TestBufferFactory "+element.toString());
            }
            System.err.println("TestBufferFactory **********END************");
        }
View Full Code Here

TOP

Related Classes of com.mobixess.jodb.core.io.IRandomAccessDataBuffer

Copyright © 2018 www.massapicom. 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.