/* This file is part of the db4o object database http://www.db4o.com Copyright (C) 2004 - 2011 Versant Corporation http://www.versant.com db4o is free software; you can redistribute it and/or modify it under the terms of version 3 of the GNU General Public License as published by the Free Software Foundation. db4o 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, see http://www.gnu.org/licenses/. */ package com.db4o.defragment; import java.io.*; import com.db4o.*; import com.db4o.internal.*; import com.db4o.internal.btree.*; /** * Second step in the defragmenting process: Fills in target file pointer slots, copies * content slots from source to target and triggers ID remapping therein by calling the * appropriate db4o/marshaller defrag() implementations. During the process, the actual address * mappings for the content slots are registered for use with string indices. * * @exclude */ final class SecondPassCommand implements PassCommand { protected final int _objectCommitFrequency; protected int _objectCount=0; public SecondPassCommand(int objectCommitFrequency) { _objectCommitFrequency = objectCommitFrequency; } public void processClass(final DefragmentServicesImpl services, final ClassMetadata classMetadata, int id,final int classIndexID) throws CorruptionException, IOException { if(services.mappedID(id,-1)==-1) { System.err.println("MAPPING NOT FOUND: "+id); } DefragmentContextImpl.processCopy(services, id, new SlotCopyHandler() { public void processCopy(DefragmentContextImpl context){ classMetadata.defragClass(context, classIndexID); } }); } public void processObjectSlot(final DefragmentServicesImpl services, final ClassMetadata classMetadata, int id) throws CorruptionException, IOException { ByteArrayBuffer sourceBuffer = services.sourceBufferByID(id); DefragmentContextImpl.processCopy(services, id, new SlotCopyHandler() { public void processCopy(DefragmentContextImpl context) { ClassMetadata.defragObject(context); if(_objectCommitFrequency>0) { _objectCount++; if(_objectCount==_objectCommitFrequency) { services.targetCommit(); services.mapping().commit(); _objectCount=0; } } } },sourceBuffer); } public void processClassCollection(final DefragmentServicesImpl services) throws CorruptionException, IOException { DefragmentContextImpl.processCopy(services, services.sourceClassCollectionID(), new SlotCopyHandler() { public void processCopy(DefragmentContextImpl context) { if (Deploy.debug) { context.readBegin(Const4.YAPCLASSCOLLECTION); } int acceptedClasses = 0; int numClassesOffset = context.targetBuffer().offset(); acceptedClasses = copyAcceptedClasses(context, acceptedClasses); writeIntAt(context.targetBuffer(), numClassesOffset, acceptedClasses); if (Deploy.debug) { context.readEnd(); } } private int copyAcceptedClasses(DefragmentContextImpl context, int acceptedClasses) { int numClasses=context.readInt(); for(int classIdx=0;classIdx<numClasses;classIdx++) { int classId = context.sourceBuffer().readInt(); if (! accept(classId)) { continue; } ++acceptedClasses; context.writeMappedID(classId); } return acceptedClasses; } private void writeIntAt(ByteArrayBuffer target, int offset, int value) { int currentOffset = target.offset(); target.seek(offset); target.writeInt(value); target.seek(currentOffset); } private boolean accept(int classId) { return services.accept(services.classMetadataForId(classId)); } }); } public void processBTree(final DefragmentServicesImpl context, BTree btree) throws CorruptionException, IOException { btree.defragBTree(context); } public void flush(DefragmentServicesImpl context) { } }