// Copyright 2017 JanusGraph Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package org.janusgraph.diskstorage.locking; import com.google.common.base.Preconditions; import org.janusgraph.diskstorage.util.time.TimestampProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Iterator; import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; /** * A singleton maintaining a globally unique map of {@link LocalLockMediator} * instances. * * @see LocalLockMediatorProvider * @author Dan LaRocque <dalaro@hopcount.org> */ public enum LocalLockMediators implements LocalLockMediatorProvider { INSTANCE; private static final Logger log = LoggerFactory .getLogger(LocalLockMediators.class); /** * Maps a namespace to the mediator responsible for the namespace. * <p> * Implementation note: for Cassandra, namespace is usually a column * family name. */ private final ConcurrentHashMap<String, LocalLockMediator<?>> mediators = new ConcurrentHashMap<String, LocalLockMediator<?>>(); @Override public <T> LocalLockMediator<T> get(String namespace, TimestampProvider times) { Preconditions.checkNotNull(namespace); @SuppressWarnings("unchecked") LocalLockMediator<T> m = (LocalLockMediator<T>)mediators.get(namespace); if (null == m) { m = new LocalLockMediator<T>(namespace, times); @SuppressWarnings("unchecked") LocalLockMediator<T> old = (LocalLockMediator<T>)mediators.putIfAbsent(namespace, m); if (null != old) m = old; else log.debug("Local lock mediator instantiated for namespace {}", namespace); } return m; } /** * Only use this in testing. * <p> * This deletes the global map of namespaces to mediators. Calling this in * production would result in undetected locking failures and data * corruption. */ public void clear() { mediators.clear(); } /** * Only use this in testing. * <p> * This deletes all entries in the global map of namespaces to mediators * whose namespace key equals the argument. * * @param prefix */ public void clear(String namespace) { Iterator<Entry<String, LocalLockMediator<?>>> iter = mediators.entrySet().iterator(); while (iter.hasNext()) { Entry<String, LocalLockMediator<?>> e = iter.next(); if (e.getKey().equals(namespace)) { iter.remove(); } } } }