blob: 0cca8c9d20188c957bbb0a2c0745374ce812a01f [file] [log] [blame]
/*
* 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();
}
}