All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.palantir.atlasdb.table.description.render.RowOrDynamicColumnRenderer Maven / Gradle / Ivy

There is a newer version: 0.1193.0
Show newest version
/*
 * (c) Copyright 2018 Palantir Technologies Inc. All rights reserved.
 *
 * 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.palantir.atlasdb.table.description.render;

import static com.palantir.atlasdb.table.description.render.ComponentRenderers.TypeName;
import static com.palantir.atlasdb.table.description.render.ComponentRenderers.VarName;
import static com.palantir.atlasdb.table.description.render.ComponentRenderers.typeName;
import static com.palantir.atlasdb.table.description.render.ComponentRenderers.varName;
import static java.lang.Math.max;

import com.google.common.base.Joiner;
import com.google.common.collect.Iterables;
import com.palantir.atlasdb.protos.generated.TableMetadataPersistence.ValueByteOrder;
import com.palantir.atlasdb.table.description.NameComponentDescription;
import com.palantir.atlasdb.table.description.NameMetadataDescription;
import com.palantir.atlasdb.table.description.ValueType;
import com.palantir.logsafe.Preconditions;
import java.util.ArrayList;
import java.util.List;

@SuppressWarnings("checkstyle:all") // too many warnings to fix
class RowOrDynamicColumnRenderer extends Renderer {
    private final String Name;
    private final NameMetadataDescription desc;
    private final boolean rangeScanAllowed;
    private final boolean isDynamicColumn;

    public RowOrDynamicColumnRenderer(
            Renderer parent,
            String Name,
            NameMetadataDescription desc,
            boolean rangeScanAllowed,
            boolean isDynamicColumn) {
        super(parent);
        this.Name = Name;
        this.desc = desc;
        Preconditions.checkArgument(
                !rangeScanAllowed || !isDynamicColumn,
                "Cannot have row range scans allowed on a dynamic column renderer.");
        this.rangeScanAllowed = rangeScanAllowed;
        this.isDynamicColumn = isDynamicColumn;
    }

    @Override
    protected void run() {
        javaDoc();
        line("public static final class ", Name, " implements Persistable, Comparable<", Name, "> {");
        {
            fields();
            line();
            staticFactory();
            line();
            constructor();
            line();
            for (NameComponentDescription comp : getRowPartsWithoutHash()) {
                getVarName(comp);
                line();
            }
            for (NameComponentDescription comp : getRowPartsWithoutHash()) {
                getVarNameFun(comp);
                line();
            }
            if (getRowPartsWithoutHash().size() == 1) {
                fromVarNameFun();
                line();
            }
            persistToBytes();
            line();
            bytesHydrator();
            line();
            if (desc.numberOfComponentsHashed() > 0) {
                renderComputeFirstNComponentsHashMethod(desc.numberOfComponentsHashed());
                line();
            }
            if (rangeScanAllowed || isDynamicColumn) {
                int firstSortedIndex = desc.getRowParts().size() - 1;
                for (; firstSortedIndex > 0; firstSortedIndex--) {
                    if (!desc.getRowParts().get(firstSortedIndex).getType().supportsRangeScans()) {
                        break;
                    }
                }
                for (int i = max(desc.numberOfComponentsHashed(), 1);
                        i <= desc.getRowParts().size() - 1;
                        i++) {
                    if (isDynamicColumn) {
                        createColumnPrefixRange(i, firstSortedIndex < i);
                    } else {
                        createPrefixRange(i, firstSortedIndex < i);
                    }
                    line();
                    prefix(i, firstSortedIndex < i);
                    line();
                }
            }
            renderToString();
            line();
            renderEquals();
            line();
            renderHashCode();
            line();
            renderCompareTo();
        }
        line("}");
    }

    private void javaDoc() {
        line("/**");
        line(" * 
");
        line(" * ", Name, " {", "");
        for (NameComponentDescription comp : desc.getRowParts()) {
            boolean descending = comp.getOrder() == ValueByteOrder.DESCENDING;
            line(" *   {@literal ", descending ? "@Descending " : "", TypeName(comp), " ", varName(comp), "};");
        }
        line(" * }", "");
        line(" * 
"); line(" */"); } private void fields() { for (NameComponentDescription comp : desc.getRowParts()) { line("private final ", typeName(comp), " ", varName(comp), ";"); } } private void staticFactory() { line("public static ", Name, " of"); renderParameterList(getRowPartsWithoutHash()); lineEnd(" {"); { if (desc.numberOfComponentsHashed() > 0) { renderComputeFirstNComponentHash(desc.numberOfComponentsHashed()); } line("return new ", Name); renderArgumentList(); lineEnd(";"); } line("}"); } private void constructor() { line("private ", Name); renderParameterList(); lineEnd(" {"); { for (NameComponentDescription comp : desc.getRowParts()) { line("this.", varName(comp), " = ", varName(comp), ";"); } } line("}"); } private void getVarName(NameComponentDescription comp) { line("public ", typeName(comp), " get", VarName(comp), "() {"); { line("return ", varName(comp), ";"); } line("}"); } private void getVarNameFun(NameComponentDescription comp) { line("public static Function<", Name, ", ", TypeName(comp), "> get", VarName(comp), "Fun() {"); { line("return new Function<", Name, ", ", TypeName(comp), ">() {"); { line("@Override"); line("public ", TypeName(comp), " apply(", Name, " row) {"); { line("return row.", varName(comp), ";"); } line("}"); } line("};"); } line("}"); } private void fromVarNameFun() { NameComponentDescription comp = Iterables.getOnlyElement(getRowPartsWithoutHash()); line("public static Function<", TypeName(comp), ", ", Name, "> from", VarName(comp), "Fun() {"); { line("return new Function<", TypeName(comp), ", ", Name, ">() {"); { line("@Override"); line("public ", Name, " apply(", TypeName(comp), " row) {"); { line("return ", Name, ".of(row);"); } line("}"); } line("};"); } line("}"); } private void persistToBytes() { line("@Override"); line("public byte[] persistToBytes() {"); { List vars = new ArrayList<>(); for (NameComponentDescription comp : desc.getRowParts()) { String var = varName(comp) + "Bytes"; vars.add(var); line("byte[] ", var, " = ", comp.getType().getPersistCode(varName(comp)), ";"); if (comp.getOrder() == ValueByteOrder.DESCENDING) { line("EncodingUtils.flipAllBitsInPlace(", var, ");"); } } line("return EncodingUtils.add(", Joiner.on(", ").join(vars), ");"); } line("}"); } private void bytesHydrator() { line("public static final Hydrator<", Name, "> BYTES_HYDRATOR = new Hydrator<", Name, ">() {"); { line("@Override"); line("public ", Name, " hydrateFromBytes(byte[] __input) {"); { line("int __index = 0;"); List vars = new ArrayList<>(); List rowParts = desc.getRowParts(); for (int i = 0; i < rowParts.size(); i++) { NameComponentDescription comp = rowParts.get(i); String var = varName(comp); vars.add(var); if (comp.getOrder() == ValueByteOrder.ASCENDING) { line(typeName(comp), " ", var, " = ", comp.getType().getHydrateCode("__input", "__index"), ";"); } else { line( typeName(comp), " ", var, " = ", comp.getType().getFlippedHydrateCode("__input", "__index"), ";"); } if (i < rowParts.size() - 1) { line("__index += ", comp.getType().getHydrateSizeCode(var), ";"); } } line("return new ", Name, "(", Joiner.on(", ").join(vars), ");"); } line("}"); } line("};"); } private void createPrefixRange(int i, boolean isSorted) { List components = getRowPartsWithoutHash().subList(0, i); line("public static RangeRequest.Builder createPrefixRange", isSorted ? "" : "Unsorted"); renderParameterList(components); lineEnd(" {"); { List vars = renderComponentBytes(components); line( "return RangeRequest.builder().prefixRange(EncodingUtils.add(", Joiner.on(", ").join(vars), "));"); } line("}"); } private void createColumnPrefixRange(int i, boolean isSorted) { List components = getRowPartsWithoutHash().subList(0, i); line("public static BatchColumnRangeSelection createPrefixRange", isSorted ? "" : "Unsorted"); renderParameterList(components); replace(")", ", int batchSize)"); lineEnd(" {"); { List vars = renderComponentBytes(components); line( "return ColumnRangeSelections.createPrefixRange(EncodingUtils.add(", Joiner.on(", ").join(vars), "), batchSize);"); } line("}"); } private List renderComponentBytes(List components) { List vars = new ArrayList<>(); if (desc.numberOfComponentsHashed() > 0) { renderComputeFirstNComponentHash(desc.numberOfComponentsHashed()); String var = NameMetadataDescription.HASH_ROW_COMPONENT_NAME + "Bytes"; vars.add(var); line( "byte[] ", var, " = ", ValueType.FIXED_LONG.getPersistCode(NameMetadataDescription.HASH_ROW_COMPONENT_NAME), ";"); } for (NameComponentDescription comp : components) { String var = varName(comp) + "Bytes"; vars.add(var); line("byte[] ", var, " = ", comp.getType().getPersistCode(varName(comp)), ";"); if (comp.getOrder() == ValueByteOrder.DESCENDING) { line("EncodingUtils.flipAllBitsInPlace(", var, ");"); } } return vars; } private void prefix(int i, boolean isSorted) { List components = getRowPartsWithoutHash().subList(0, i); line("public static Prefix prefix", isSorted ? "" : "Unsorted"); renderParameterList(components); lineEnd(" {"); { List vars = new ArrayList<>(); if (desc.numberOfComponentsHashed() > 0) { renderComputeFirstNComponentHash(desc.numberOfComponentsHashed()); String var = NameMetadataDescription.HASH_ROW_COMPONENT_NAME + "Bytes"; vars.add(var); line( "byte[] ", var, " = ", ValueType.FIXED_LONG.getPersistCode(NameMetadataDescription.HASH_ROW_COMPONENT_NAME), ";"); } for (NameComponentDescription comp : components) { String var = varName(comp) + "Bytes"; vars.add(var); line("byte[] ", var, " = ", comp.getType().getPersistCode(varName(comp)), ";"); if (comp.getOrder() == ValueByteOrder.DESCENDING) { line("EncodingUtils.flipAllBitsInPlace(", var, ");"); } } line("return new Prefix(EncodingUtils.add(", Joiner.on(", ").join(vars), "));"); } line("}"); } private void renderComputeFirstNComponentHash(int numberOfComponentsHashed) { List components = getRowPartsWithoutHash().subList(0, numberOfComponentsHashed); List vars = new ArrayList<>(); for (NameComponentDescription comp : components) { vars.add(varName(comp)); } line( "long ", NameMetadataDescription.HASH_ROW_COMPONENT_NAME, " = computeHashFirstComponents(", Joiner.on(", ").join(vars), ");"); } private void renderComputeFirstNComponentsHashMethod(int numberOfComponentsHashed) { List components = getRowPartsWithoutHash().subList(0, numberOfComponentsHashed); line("public static long computeHashFirstComponents"); renderParameterList(components); lineEnd(" {"); { List vars = new ArrayList<>(); for (NameComponentDescription comp : components) { String var = varName(comp) + "Bytes"; vars.add(var); line("byte[] ", var, " = ", comp.getType().getPersistCode(varName(comp)), ";"); if (comp.getOrder() == ValueByteOrder.DESCENDING) { line("EncodingUtils.flipAllBitsInPlace(", var, ");"); } } line( "return Hashing.murmur3_128().hashBytes(EncodingUtils.add(", Joiner.on(", ").join(vars), ")).asLong();"); } line("}"); } private void renderToString() { line("@Override"); line("public String toString() {"); { line("return MoreObjects.toStringHelper(getClass().getSimpleName())"); for (NameComponentDescription comp : desc.getRowParts()) { line(" .add(\"", varName(comp), "\", ", varName(comp), ")"); } line(" .toString();"); } line("}"); } private void renderEquals() { line("@Override"); line("public boolean equals(Object obj) {"); { line("if (this == obj) {"); { line("return true;"); } line("}"); line("if (obj == null) {"); { line("return false;"); } line("}"); line("if (getClass() != obj.getClass()) {"); { line("return false;"); } line("}"); line(Name, " other = (", Name, ") obj;"); line("return"); for (NameComponentDescription comp : desc.getRowParts()) { if (comp.getType() == ValueType.BLOB || comp.getType() == ValueType.SIZED_BLOB) { lineEnd(" Arrays.equals(", varName(comp), ", other.", varName(comp), ") &&"); } else { lineEnd(" Objects.equals(", varName(comp), ", other.", varName(comp), ") &&"); } } replace(" &&", ";"); } line("}"); } private void renderHashCode() { line("@Override"); line("public int hashCode() {"); { renderHashCodeMethodCall(); } line("}"); } private void renderHashCodeMethodCall() { if (desc.getRowParts().size() > 1) { renderHashCodeMethodCall("return Arrays.deepHashCode(new Object[]{ ", " });"); } else { ValueType type = desc.getRowParts().get(0).getType(); String clazz = type.getJavaClass().isPrimitive() ? type.getJavaObjectClass().getSimpleName() : type.getJavaClass().isArray() ? "Arrays" : "Objects"; renderHashCodeMethodCall("return " + clazz + ".hashCode(", ");"); } } private void renderHashCodeMethodCall(String methodOpening, String methodClosing) { line(methodOpening); renderVariableList(); replace(", ", methodClosing); } private void renderVariableList() { for (NameComponentDescription comp : desc.getRowParts()) { lineEnd(varName(comp), ", "); } } private void renderCompareTo() { line("@Override"); line("public int compareTo(", Name, " o) {"); { line("return ComparisonChain.start()"); for (NameComponentDescription comp : desc.getRowParts()) { String comparator = TypeName(comp).equals("byte[]") ? ", UnsignedBytes.lexicographicalComparator()" : ""; line(" .compare(this.", varName(comp), ", o.", varName(comp), comparator, ")"); } line(" .result();"); } line("}"); } private void renderParameterList() { renderParameterList(desc.getRowParts()); } private void renderParameterList(List components) { lineEnd("("); for (NameComponentDescription comp : components.subList(0, components.size())) { lineEnd(typeName(comp), " ", varName(comp), ", "); } replace(", ", ")"); } private void renderArgumentList() { renderArgumentList(desc.getRowParts().size()); } private void renderArgumentList(int i) { lineEnd("("); for (NameComponentDescription comp : desc.getRowParts().subList(0, i)) { lineEnd(varName(comp), ", "); } replace(", ", ")"); } private List getRowPartsWithoutHash() { if (desc.numberOfComponentsHashed() == 0) { return desc.getRowParts(); } else { return desc.getRowParts().subList(1, desc.getRowParts().size()); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy