com.palantir.atlasdb.keyvalue.partition.util.RowResultUtil.java Source code

Java tutorial

Introduction

Here is the source code for com.palantir.atlasdb.keyvalue.partition.util.RowResultUtil.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.keyvalue.partition.util;

import java.util.Arrays;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;

import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;
import com.google.common.collect.PeekingIterator;
import com.google.common.collect.Sets;
import com.google.common.primitives.UnsignedBytes;
import com.palantir.atlasdb.keyvalue.api.Cell;
import com.palantir.atlasdb.keyvalue.api.RowResult;
import com.palantir.atlasdb.keyvalue.api.Value;
import com.palantir.atlasdb.keyvalue.partition.quorum.QuorumParameters;
import com.palantir.common.base.Throwables;

public class RowResultUtil {

    public static Map<Cell, Value> getNewestValue(RowResult<Value> row) {

        Map<Cell, Value> result = Maps.newHashMap();

        for (Map.Entry<Cell, Value> e : row.getCells()) {
            final Cell cell = e.getKey();
            final Value val = e.getValue();
            if (!result.containsKey(cell) || result.get(cell).getTimestamp() < val.getTimestamp()) {
                result.put(cell, val);
            }
        }

        return result;

    }

    /*
     * Get all values for the row of the first returned value. Return the newest value.
     */
    public static RowResult<Value> mergeResults(PeekingIterator<RowResult<Value>> it,
            QuorumParameters.QuorumRequestParameters quorumRequestParameters) {
        Preconditions.checkArgument(it.hasNext());

        byte[] row = it.peek().getRowName();
        final SortedMap<byte[], Value> result = Maps.newTreeMap(UnsignedBytes.lexicographicalComparator());
        int failCount = 0;
        int succCount = 0;
        RuntimeException lastSuppressedException = null;

        while (it.hasNext() && Arrays.equals(it.peek().getRowName(), row)) {
            try {
                for (Map.Entry<Cell, Value> e : it.next().getCells()) {
                    final byte[] col = e.getKey().getColumnName();

                    // Assert that there is not contradictory data
                    if (result.containsKey(col) && e.getValue().getTimestamp() == result.get(col).getTimestamp()) {
                        assert Arrays.equals(result.get(col).getContents(), e.getValue().getContents());
                    }

                    if (!result.containsKey(col) || result.get(col).getTimestamp() < e.getValue().getTimestamp()) {
                        result.put(col, e.getValue());
                    }
                }
                succCount++;
            } catch (RuntimeException e) {
                System.err.println("Could not read for rangeRequest.");
                failCount++;
                if (failCount >= quorumRequestParameters.getFailureFactor()) {
                    throw Throwables.rewrapAndThrowUncheckedException("Could not get enough reads.", e);
                }
                lastSuppressedException = e;
            }
        }

        if (succCount < quorumRequestParameters.getSuccessFactor()) {
            if (lastSuppressedException != null) {
                throw lastSuppressedException;
            } else {
                throw new RuntimeException("Not enough reads for row " + Arrays.toString(row));
            }
        }

        return RowResult.create(row, result);
    }

    // Any failure will cause an exception
    public static RowResult<Set<Value>> allResults(PeekingIterator<RowResult<Set<Value>>> it) {
        Preconditions.checkArgument(it.hasNext());

        final byte[] row = it.peek().getRowName();
        SortedMap<byte[], Set<Value>> result = Maps.newTreeMap(UnsignedBytes.lexicographicalComparator());
        while (it.hasNext() && Arrays.equals(row, it.peek().getRowName())) {
            RowResult<Set<Value>> kvsResult = it.next();
            for (Map.Entry<Cell, Set<Value>> e : kvsResult.getCells()) {
                final byte[] col = e.getKey().getColumnName();
                if (!result.containsKey(col)) {
                    result.put(col, Sets.<Value>newHashSet());
                }
                result.get(col).addAll(e.getValue());
            }
        }

        // Assert that there is no multiple values for same key
        for (Set<Value> cell : result.values()) {
            for (Value val : cell) {
                for (Value otherVal : cell) {
                    if (val != otherVal) {
                        assert val.getTimestamp() != otherVal.getTimestamp();
                    }
                }
            }
        }

        return RowResult.create(row, result);
    }

    // Any failure will cause an exception
    public static RowResult<Set<Long>> allTimestamps(PeekingIterator<RowResult<Set<Long>>> it) {
        Preconditions.checkArgument(it.hasNext());

        final byte[] row = it.peek().getRowName();
        final SortedMap<byte[], Set<Long>> result = Maps.newTreeMap(UnsignedBytes.lexicographicalComparator());
        while (it.hasNext() && Arrays.equals(row, it.peek().getRowName())) {
            RowResult<Set<Long>> kvsResult = it.next();
            for (Map.Entry<Cell, Set<Long>> e : kvsResult.getCells()) {
                if (!result.containsKey(e.getKey().getColumnName())) {
                    result.put(e.getKey().getColumnName(), Sets.<Long>newHashSet());
                }
                result.get(e.getKey().getColumnName()).addAll(e.getValue());
            }
        }
        return RowResult.create(row, result);
    }
}