com.palantir.atlasdb.schema.RowTransformers.java Source code

Java tutorial

Introduction

Here is the source code for com.palantir.atlasdb.schema.RowTransformers.java

Source

/**
 * Copyright 2015 Palantir Technologies
 *
 * Licensed under the BSD-3 License (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://opensource.org/licenses/BSD-3-Clause
 *
 * 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.palantir.atlasdb.schema;

import java.util.List;
import java.util.Set;

import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.palantir.atlasdb.ptobject.EncodingUtils;
import com.palantir.atlasdb.ptobject.EncodingUtils.EncodingType;

public class RowTransformers {

    private RowTransformers() {
        // cannot instantiate
    }

    public static class RowComponent {
        private final int index;
        private final EncodingType type;

        public RowComponent(int index, EncodingType type) {
            this.index = index;
            this.type = type;
        }

        public static RowComponent of(int index, EncodingType type) {
            return new RowComponent(index, type);
        }

        public int getIndex() {
            return index;
        }

        public EncodingType getType() {
            return type;
        }

        public static final Function<RowComponent, Integer> TO_INDEX = new Function<RowComponent, Integer>() {
            @Override
            public Integer apply(RowComponent component) {
                return component.getIndex();
            }
        };

        public static final Function<RowComponent, EncodingType> TO_TYPE = new Function<RowComponent, EncodingType>() {
            @Override
            public EncodingType apply(RowComponent component) {
                return component.getType();
            }
        };
    }

    /**
     * Returns a function that permutes the order of the components of each row without changing their types.
     */
    public static Function<byte[], byte[]> rowNamePermutation(List<EncodingType> initialTypes,
            List<Integer> permutation) {
        Preconditions.checkArgument(initialTypes.size() == permutation.size());
        List<RowComponent> fullPermutation = Lists.newArrayListWithCapacity(permutation.size());
        for (int i = 0; i < initialTypes.size(); i++) {
            fullPermutation.add(RowComponent.of(permutation.get(i), initialTypes.get(permutation.get(i))));
        }
        return rowNamePermuformation(initialTypes, fullPermutation);
    }

    /**
     * Returns a function that changes the type of the components in each row without changing their order.
     */
    public static Function<byte[], byte[]> rowNameTransformation(List<EncodingType> initialTypes,
            List<EncodingType> finalTypes) {
        Preconditions.checkArgument(initialTypes.size() == finalTypes.size());
        List<RowComponent> fullPermutation = Lists.newArrayListWithCapacity(initialTypes.size());
        for (int i = 0; i < initialTypes.size(); i++) {
            fullPermutation.add(RowComponent.of(i, finalTypes.get(i)));
        }
        return rowNamePermuformation(initialTypes, fullPermutation);
    }

    /**
     * Returns a function that changes the type and ordering of the components in each row.
     */
    public static Function<byte[], byte[]> rowNamePermuformation(final List<EncodingType> initialTypes,
            List<RowComponent> permutation) {
        Preconditions.checkArgument(initialTypes.size() == permutation.size());
        Set<Integer> outputIndices = ImmutableSet.copyOf(Iterables.transform(permutation, RowComponent.TO_INDEX));
        Preconditions.checkArgument(outputIndices.size() == permutation.size(),
                "Permutation maps multiple components to the same index.");
        for (int index : outputIndices) {
            Preconditions.checkElementIndex(index, permutation.size());
        }

        final List<Integer> indexPermutation = ImmutableList
                .copyOf(Lists.transform(permutation, RowComponent.TO_INDEX));
        final List<EncodingType> finalTypes = ImmutableList
                .copyOf(Lists.transform(permutation, RowComponent.TO_TYPE));
        return new Function<byte[], byte[]>() {
            @Override
            public byte[] apply(byte[] input) {
                List<Object> initialValues = EncodingUtils.fromBytes(input, initialTypes);
                List<Object> finalValues = Lists.newArrayListWithCapacity(indexPermutation.size());
                for (int i = 0; i < indexPermutation.size(); i++) {
                    finalValues.add(initialValues.get(indexPermutation.get(i)));
                }
                return EncodingUtils.toBytes(finalTypes, finalValues);
            }
        };
    }
}