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

com.yahoo.sketches.quantiles.ItemsByteArrayImpl Maven / Gradle / Ivy

/*
 * Copyright 2017, Yahoo! Inc. Licensed under the terms of the
 * Apache License 2.0. See LICENSE file at the project root for terms.
 */

package com.yahoo.sketches.quantiles;

import static com.yahoo.sketches.quantiles.PreambleUtil.COMPACT_FLAG_MASK;
import static com.yahoo.sketches.quantiles.PreambleUtil.EMPTY_FLAG_MASK;
import static com.yahoo.sketches.quantiles.PreambleUtil.ORDERED_FLAG_MASK;
import static com.yahoo.sketches.quantiles.PreambleUtil.insertFamilyID;
import static com.yahoo.sketches.quantiles.PreambleUtil.insertFlags;
import static com.yahoo.sketches.quantiles.PreambleUtil.insertK;
import static com.yahoo.sketches.quantiles.PreambleUtil.insertN;
import static com.yahoo.sketches.quantiles.PreambleUtil.insertPreLongs;
import static com.yahoo.sketches.quantiles.PreambleUtil.insertSerVer;

import java.lang.reflect.Array;
import java.util.Arrays;

import com.yahoo.memory.Memory;
import com.yahoo.memory.NativeMemory;
import com.yahoo.sketches.ArrayOfItemsSerDe;
import com.yahoo.sketches.Family;

/**
 * The items to byte array algorithms.
 *
 * @author Lee Rhodes
 * @author Alexander Saydakov
 */
final class ItemsByteArrayImpl {

  private ItemsByteArrayImpl() {}

  static  byte[] toByteArray(final ItemsSketch sketch, final boolean ordered,
      final ArrayOfItemsSerDe serDe) {
    final boolean empty = sketch.isEmpty();

    final int flags = (empty ? EMPTY_FLAG_MASK : 0)
        | (ordered ? ORDERED_FLAG_MASK : 0)
        | COMPACT_FLAG_MASK; //always compact

    if (empty) {
      final byte[] outByteArr = new byte[Long.BYTES];
      final Memory memOut = new NativeMemory(outByteArr);
      final Object memObj = memOut.array();
      final long memAdd = memOut.getCumulativeOffset(0L);
      final int preLongs = 1;
      insertPre0(memObj, memAdd, preLongs, flags, sketch.getK());
      return outByteArr;
    }

    //not empty
    final T[] dataArr = combinedBufferToItemsArray(sketch, ordered); //includes min and max

    final int preLongs = 2;
    final byte[] itemsByteArr = serDe.serializeToByteArray(dataArr);
    final int numOutBytes = (preLongs << 3) + itemsByteArr.length;
    final byte[] outByteArr = new byte[numOutBytes];
    final Memory memOut = new NativeMemory(outByteArr);
    final long cumOffset = memOut.getCumulativeOffset(0L);

    //insert preamble
    insertPre0(outByteArr, cumOffset, preLongs, flags, sketch.getK());
    insertN(outByteArr, cumOffset, sketch.getN());

    //insert data
    memOut.putByteArray(preLongs << 3, itemsByteArr, 0, itemsByteArr.length);
    return outByteArr;
  }

  /**
   * Returns an array of items in compact form, including min and max extracted from the
   * Combined Buffer.
   * @param ordered true if the desired form of the resulting array has the base buffer sorted.
   * @return an array of items, including min and max extracted from the Combined Buffer.
   */
  @SuppressWarnings("unchecked")
  private static  T[] combinedBufferToItemsArray(final ItemsSketch sketch,
      final boolean ordered) {
    T[] outArr = null;
    final int extra = 2; // extra space for min and max values
    final int outArrCap = sketch.getRetainedItems();
    final T minValue = sketch.getMinValue();
    outArr = (T[]) Array.newInstance(minValue.getClass(), outArrCap + extra);

    //Load min, max
    outArr[0] = minValue;
    outArr[1] = sketch.getMaxValue();
    final int baseBufferCount = sketch.getBaseBufferCount();
    final Object[] combinedBuffer = sketch.getCombinedBuffer();

    //Load base buffer
    System.arraycopy(combinedBuffer, 0, outArr, extra, baseBufferCount);

    //Load levels
    long bitPattern = sketch.getBitPattern();
    if (bitPattern > 0) {
      final int k = sketch.getK();
      int index = extra + baseBufferCount;
      for (int level = 0; bitPattern != 0L; level++, bitPattern >>>= 1) {
        if ((bitPattern & 1L) > 0L) {
          System.arraycopy(combinedBuffer, (2 + level) * k, outArr, index, k);
          index += k;
        }
      }
    }
    if (ordered) {
      Arrays.sort(outArr, extra, baseBufferCount + extra, sketch.getComparator());
    }
    return outArr;
  }

  private static void insertPre0(final Object memObj, final long memAdd,
      final int preLongs, final int flags, final int k) {
    insertPreLongs(memObj, memAdd, preLongs);
    insertSerVer(memObj, memAdd, ItemsUtil.ITEMS_SER_VER);
    insertFamilyID(memObj, memAdd, Family.QUANTILES.getID());
    insertFlags(memObj, memAdd, flags);
    insertK(memObj, memAdd, k);
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy