/* * The contents of this file are subject to the terms of the Common Development and * Distribution License (the License). You may not use this file except in compliance with the * License. * * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the * specific language governing permission and limitations under the License. * * When distributing Covered Software, include this CDDL Header Notice in each file and include * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL * Header, with the fields enclosed by brackets [] replaced by your own identifying * information: "Portions Copyright [year] [name of copyright owner]". * * Copyright 2013-2016 ForgeRock AS. */ package org.opends.server.replication.server; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentSkipListMap; import net.jcip.annotations.ThreadSafe; import org.opends.server.replication.common.CSN; import org.opends.server.replication.common.MultiDomainServerState; import org.forgerock.opendj.ldap.DN; /** * This is the changelog state stored in the changelogStateDB. For each * replication domain, it contains: * *

* This class is used during replication initialization to decouple the code * that reads the changelogStateDB from the code that makes use of its data. */ @ThreadSafe public class ChangelogState { private final ConcurrentSkipListMap domainToGenerationId = new ConcurrentSkipListMap<>(); private final ConcurrentSkipListMap> domainToServerIds = new ConcurrentSkipListMap<>(); private final MultiDomainServerState offlineReplicas = new MultiDomainServerState(); /** * Sets the generationId for the supplied replication domain. * * @param baseDN * the targeted replication domain baseDN * @param generationId * the generation Id to set */ public void setDomainGenerationId(DN baseDN, long generationId) { domainToGenerationId.put(baseDN, generationId); } /** * Adds the serverId to the serverIds list of the supplied replication domain. * * @param serverId * the serverId to add * @param baseDN * the targeted replication domain baseDN */ public void addServerIdToDomain(int serverId, DN baseDN) { Set serverIds = domainToServerIds.get(baseDN); if (serverIds == null) { serverIds = new HashSet<>(); final Set existingServerIds = domainToServerIds.putIfAbsent(baseDN, serverIds); if (existingServerIds != null) { serverIds = existingServerIds; } } serverIds.add(serverId); } /** * Adds the following replica information to the offline list. * * @param baseDN * the baseDN of the offline replica * @param offlineCSN * the CSN (serverId + timestamp) of the offline replica */ public void addOfflineReplica(DN baseDN, CSN offlineCSN) { offlineReplicas.update(baseDN, offlineCSN); } /** * Removes the following replica information from the offline list. * * @param baseDN * the baseDN of the offline replica * @param serverId * the serverId that is not offline anymore */ public void removeOfflineReplica(DN baseDN, int serverId) { CSN csn; do { csn = offlineReplicas.getCSN(baseDN, serverId); } while (csn != null && !offlineReplicas.removeCSN(baseDN, csn)); } /** * Returns the Map of domainBaseDN => generationId. * * @return a Map of domainBaseDN => generationId */ public Map getDomainToGenerationId() { return domainToGenerationId; } /** * Returns the Map of domainBaseDN => List<serverId>. * * @return a Map of domainBaseDN => List<serverId>. */ public Map> getDomainToServerIds() { return domainToServerIds; } /** * Returns the internal MultiDomainServerState for offline replicas. * * @return the MultiDomainServerState for offline replicas. */ public MultiDomainServerState getOfflineReplicas() { return offlineReplicas; } /** * Returns whether the current ChangelogState is equal to the provided * ChangelogState. *

* Note: Only use for tests!!
* This method should only be used by tests because it creates a lot of * intermediate objects which is not suitable for production. * * @param other * the ChangelogState to compare with * @return true if the current ChangelogState is equal to the provided * ChangelogState, false otherwise. */ public boolean isEqualTo(ChangelogState other) { if (other == null) { return false; } if (this == other) { return true; } return domainToGenerationId.equals(other.domainToGenerationId) && domainToServerIds.equals(other.domainToServerIds) // Note: next line is not suitable for production // because it creates lots of Lists and Maps && offlineReplicas.getSnapshot().equals(other.offlineReplicas.getSnapshot()); } /** {@inheritDoc} */ @Override public String toString() { return "domainToGenerationId=" + domainToGenerationId + ", domainToServerIds=" + domainToServerIds + ", offlineReplicas=" + offlineReplicas; } }