blob: f680ec941f125d243247148804c5f092ec638964 [file] [log] [blame]
/*
*
* 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
{
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 = new Transformation[0];
moreContents = new MoreContentsHolder[0];
}
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;
}
}