/* * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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.apache.cassandra.db.transform; import java.util.Arrays; class Stack { public static final Transformation[] EMPTY_TRANSFORMATIONS = new Transformation[0]; public static final MoreContentsHolder[] EMPTY_MORE_CONTENTS_HOLDERS = new MoreContentsHolder[0]; static final Stack EMPTY = new Stack(); Transformation[] stack; int length; // number of used stack entries MoreContentsHolder[] moreContents; // stack of more contents providers (if any; usually zero or one) // an internal placeholder for a MoreContents, storing the associated stack length at time it was applied static class MoreContentsHolder { final MoreContents moreContents; int length; private MoreContentsHolder(MoreContents moreContents, int length) { this.moreContents = moreContents; this.length = length; } } Stack() { stack = EMPTY_TRANSFORMATIONS; moreContents = EMPTY_MORE_CONTENTS_HOLDERS; } Stack(Stack copy) { stack = copy.stack; length = copy.length; moreContents = copy.moreContents; } void add(Transformation add) { if (length == stack.length) stack = resize(stack); stack[length++] = add; } void add(MoreContents more) { this.moreContents = Arrays.copyOf(moreContents, moreContents.length + 1); this.moreContents[moreContents.length - 1] = new MoreContentsHolder(more, length); } private static <E> E[] resize(E[] array) { int newLen = array.length == 0 ? 5 : array.length * 2; return Arrays.copyOf(array, newLen); } // reinitialise the transformations after a moreContents applies void refill(Stack prefix, MoreContentsHolder holder, int index) { // drop the transformations that were present when the MoreContents was attached, // and prefix any transformations in the new contents (if it's a transformer) moreContents = splice(prefix.moreContents, prefix.moreContents.length, moreContents, index, moreContents.length); stack = splice(prefix.stack, prefix.length, stack, holder.length, length); length += prefix.length - holder.length; holder.length = prefix.length; } private static <E> E[] splice(E[] prefix, int prefixCount, E[] keep, int keepFrom, int keepTo) { int keepCount = keepTo - keepFrom; int newCount = prefixCount + keepCount; if (newCount > keep.length) keep = Arrays.copyOf(keep, newCount); if (keepFrom != prefixCount) System.arraycopy(keep, keepFrom, keep, prefixCount, keepCount); if (prefixCount != 0) System.arraycopy(prefix, 0, keep, 0, prefixCount); return keep; } }