/* 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.drs.db4o; import java.util.*; import com.db4o.*; import com.db4o.ext.*; import com.db4o.foundation.*; import com.db4o.internal.*; import com.db4o.query.*; /** * tracks the version of the last replication between * two Objectcontainers. * This class is persistent. It can't be moved to a * different package and field names can not be changed. * * @exclude * @persistent */ public class ReplicationRecord implements Internal4{ public Db4oDatabase _youngerPeer; public Db4oDatabase _olderPeer; public long _version; public long[] _concurrentTimestamps; public ReplicationRecord(){ } public ReplicationRecord(Db4oDatabase younger, Db4oDatabase older){ _youngerPeer = younger; _olderPeer = older; } public void setVersion(long version){ _version = version; } public void store(ObjectContainerBase container){ store(container.checkTransaction()); } public void store(Transaction trans){ ObjectContainerBase container = trans.container(); container.showInternalClasses(true); try { container.storeAfterReplication(trans, this, container.updateDepthProvider().forDepth(Integer.MAX_VALUE), false); } finally { container.showInternalClasses(false); } } public static ReplicationRecord beginReplication(Transaction transA, Transaction transB){ ObjectContainerBase peerA = transA.container(); ObjectContainerBase peerB = transB.container(); Db4oDatabase dbA = ((InternalObjectContainer)peerA).identity(); Db4oDatabase dbB = ((InternalObjectContainer)peerB).identity(); dbB.bind(transA); dbA.bind(transB); Db4oDatabase younger = null; Db4oDatabase older = null; if(dbA.isOlderThan(dbB)){ younger = dbB; older = dbA; }else{ younger = dbA; older = dbB; } ReplicationRecord rrA = queryForReplicationRecord(peerA, transA, younger, older); ReplicationRecord rrB = queryForReplicationRecord(peerB, transB, younger, older); if(rrA == null){ if(rrB == null){ return new ReplicationRecord(younger, older); } rrB.store(peerA); return rrB; } if(rrB == null){ rrA.store(peerB); return rrA; } if(rrA != rrB){ peerB.showInternalClasses(true); try { int id = peerB.getID(transB, rrB); peerB.bind(transB, rrA, id); } finally { peerB.showInternalClasses(false); } } return rrA; } public static ReplicationRecord queryForReplicationRecord(ObjectContainerBase container, Transaction trans, Db4oDatabase younger, Db4oDatabase older) { container.showInternalClasses(true); try { Query q = container.query(trans); q.constrain(ReplicationRecord.class); q.descend("_youngerPeer").constrain(younger).identity(); q.descend("_olderPeer").constrain(older).identity(); ObjectSet objectSet = q.execute(); if(objectSet.hasNext()){ ReplicationRecord replicationRecord = (ReplicationRecord) objectSet.next(); container.activate(replicationRecord, Integer.MAX_VALUE); return replicationRecord; } return null; } finally { container.showInternalClasses(false); } } public void concurrentTimestamps(List<Long> concurrentTimestamps) { _concurrentTimestamps = Arrays4.toLongArray(concurrentTimestamps); } public long[] concurrentTimestamps(){ return _concurrentTimestamps; } }