com.swirlds.common.merkle.route.internal.BinaryMerkleRouteIterator 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) 2020-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.route.internal;
import static com.swirlds.common.merkle.route.internal.BinaryMerkleRoute.getBitAtIndex;
import static com.swirlds.common.merkle.route.internal.BinaryMerkleRoute.getNumberOfStepsInInt;
import com.swirlds.common.merkle.exceptions.MerkleRouteException;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* This iterator walks over the steps in a binary merkle route.
*/
public class BinaryMerkleRouteIterator implements Iterator {
/**
* The route that is being iterated over.
*/
private int[] routeData;
/**
* The index of the integer in the route that will be read next.
*/
private int index;
/**
* The index of the bit within the current integer that will be read next (if next step is binary).
*/
private int bitIndex;
/**
* The total number of steps in the current integer.
*/
private int stepsInInt;
/**
* The integer data that will be read from next.
*/
private int nextData;
/**
* The next value to be returned by the iterator (if not null).
*/
private Integer next;
/**
* Create a new iterator.
*
* @param routeData
* a route to iterate
*/
public BinaryMerkleRouteIterator(int[] routeData) {
reset(routeData);
}
protected BinaryMerkleRouteIterator() {}
/**
* Reset the iterator with a new route. Useful for recycling this object.
*
* @param route
* The new route to iterate.
*/
public void reset(int[] route) {
this.routeData = route;
index = 0;
next = null;
prepareNextInt();
}
/**
* Count the number of steps in the next integer and advance the index.
*/
private void prepareNextInt() {
if (routeData == null) {
return;
}
if (routeData.length == 0) {
return;
}
nextData = routeData[index];
index++;
if (nextData == 0) {
throw new MerkleRouteException("Routes should not contain 0s.");
} else if (nextData > 0) {
stepsInInt = 1;
} else {
stepsInInt = getNumberOfStepsInInt(nextData);
bitIndex = 0;
}
}
private void findNext() {
if (next != null) {
return;
}
if (routeData == null) {
return;
}
if (stepsInInt == 0) {
if (index >= routeData.length) {
return;
}
prepareNextInt();
}
if (nextData > 0) {
next = nextData;
} else {
next = getBitAtIndex(nextData, bitIndex + 1);
bitIndex++;
}
stepsInInt--;
}
@Override
public boolean hasNext() {
findNext();
return next != null;
}
@Override
public Integer next() {
findNext();
if (next == null) {
throw new NoSuchElementException();
}
Integer ret = next;
next = null;
return ret;
}
}