com.swirlds.common.merkle.impl.internal.AbstractMerkleNode Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of swirlds-common Show documentation
Show all versions of swirlds-common Show documentation
Swirlds is a software platform designed to build fully-distributed applications that harness the power of the cloud without servers. Now you can develop applications with fairness in decision making, speed, trust and reliability, at a fraction of the cost of traditional server-based platforms.
/*
* Copyright (C) 2018-2024 Hedera Hashgraph, LLC
*
* 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 com.swirlds.common.merkle.impl.internal;
import static com.swirlds.common.merkle.route.MerkleRouteFactory.getEmptyRoute;
import com.swirlds.base.state.Mutable;
import com.swirlds.common.crypto.Hash;
import com.swirlds.common.crypto.Hashable;
import com.swirlds.common.merkle.MerkleNode;
import com.swirlds.common.merkle.exceptions.MerkleRouteException;
import com.swirlds.common.merkle.impl.PartialMerkleLeaf;
import com.swirlds.common.merkle.interfaces.HasMerkleRoute;
import com.swirlds.common.merkle.interfaces.MerkleType;
import com.swirlds.common.merkle.route.MerkleRoute;
import com.swirlds.common.utility.AbstractReservable;
import java.beans.Transient;
/**
* This class implements boilerplate functionality for a {@link MerkleNode}.
*/
public abstract sealed class AbstractMerkleNode extends AbstractReservable
implements Hashable, HasMerkleRoute, Mutable, MerkleType permits PartialMerkleLeaf, AbstractMerkleInternal {
private boolean immutable;
private MerkleRoute route;
private Hash hash = null;
protected AbstractMerkleNode() {
immutable = false;
route = getEmptyRoute();
}
protected AbstractMerkleNode(final AbstractMerkleNode that) {
this.route = that.getRoute();
}
/**
* {@inheritDoc}
*/
@Override
public Hash getHash() {
return hash;
}
/**
* {@inheritDoc}
*/
@Override
public void setHash(final Hash hash) {
this.hash = hash;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isImmutable() {
return immutable;
}
/**
* Specify the immutability status of the node.
*
* @param immutable
* if this node should be immutable
*/
@Transient
public void setImmutable(final boolean immutable) {
this.immutable = immutable;
}
/**
* {@inheritDoc}
*/
@Override
public MerkleRoute getRoute() {
return route;
}
/**
* {@inheritDoc}
*/
@Override
public void setRoute(final MerkleRoute route) {
if (!(getRoute() == route || getRoute().equals(route)) && getReservationCount() > 1) {
// If you see this exception, the most likely culprit is that you are attempting to "move" a merkle
// node from one position to another but the merkle node has multiple parents. If this operation was
// allowed to proceed, a node in multiple trees would have the incorrect route in at least one of those
// trees. Instead of moving the node, make a copy and move the copy.
throw new MerkleRouteException("Routes can not be set unless the reservation count is 0 or 1. (type = "
+ this.getClass().getName() + ", reservation count = " + getReservationCount() + ", route = "
+ getRoute() + ", new route = " + route + ")");
}
this.route = route;
}
/**
* Perform any required cleanup for this node, if necessary.
*/
protected void destroyNode() {
// override if needed
}
/**
* {@inheritDoc}
*/
@Override
protected void onDestroy() {
destroyNode();
}
}