/* * Copyright 2016-present Open Networking Laboratory * * 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.onosproject.store.primitives.resources.impl; import java.util.function.Function; import org.onosproject.store.service.MapEvent; import org.onosproject.store.service.Versioned; import com.google.common.base.MoreObjects; /** * Result of a map entry update operation. * <p> * Both old and new values are accessible along with a flag that indicates if the * the value was updated. If flag is false, oldValue and newValue both * point to the same unmodified value. * * @param <K> key type * @param <V> result type */ public class MapEntryUpdateResult<K, V> { public enum Status { /** * Indicates a successful update. */ OK, /** * Indicates a noop i.e. existing and new value are both null. */ NOOP, /** * Indicates a failed update due to a write lock. */ WRITE_LOCK, /** * Indicates a failed update due to a precondition check failure. */ PRECONDITION_FAILED } private final String mapName; private Status status; private final K key; private final Versioned<V> oldValue; private final Versioned<V> newValue; public MapEntryUpdateResult(Status status, String mapName, K key, Versioned<V> oldValue, Versioned<V> newValue) { this.status = status; this.mapName = mapName; this.key = key; this.oldValue = oldValue; this.newValue = newValue; } /** * Returns {@code true} if the update was successful. * @return {@code true} if yes, {@code false} otherwise */ public boolean updated() { return status == Status.OK; } /** * Returns the map name. * @return map name */ public String mapName() { return mapName; } /** * Returns the update status. * @return update status */ public Status status() { return status; } /** * Returns the map key. * @return key */ public K key() { return key; } /** * Returns the old value. * @return the previous value associated with key if updated was successful, otherwise current value */ public Versioned<V> oldValue() { return oldValue; } /** * Returns the new value after update. * @return if updated was unsuccessful, this is same as old value */ public Versioned<V> newValue() { return newValue; } /** * Maps to another instance with different key and value types. * @param keyTransform transformer to use for transcoding keys * @param valueMapper mapper to use for transcoding values * @return new instance * @param <K1> key type of returned {@code MapEntryUpdateResult} * @param <V1> value type of returned {@code MapEntryUpdateResult} */ public <K1, V1> MapEntryUpdateResult<K1, V1> map(Function<K, K1> keyTransform, Function<V, V1> valueMapper) { return new MapEntryUpdateResult<>(status, mapName, keyTransform.apply(key), oldValue == null ? null : oldValue.map(valueMapper), newValue == null ? null : newValue.map(valueMapper)); } /** * Return the map event that will be generated as a result of this update. * @return map event. if update was unsuccessful, this returns {@code null} */ public MapEvent<K, V> toMapEvent() { if (!updated()) { return null; } else { return new MapEvent<>(mapName(), key(), newValue, oldValue); } } @Override public String toString() { return MoreObjects.toStringHelper(MapEntryUpdateResult.class) .add("mapName", mapName) .add("status", status) .add("key", key) .add("oldValue", oldValue) .add("newValue", newValue) .toString(); } }