| /* |
| * Copyright 2015, 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.hll; |
| |
| import com.yahoo.sketches.memory.Memory; |
| import com.yahoo.sketches.memory.NativeMemory; |
| |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.Comparator; |
| import java.util.List; |
| |
| /** |
| * @author Kevin Lang |
| */ |
| class OnHeapImmutableCompactFields implements Fields { |
| public static OnHeapImmutableCompactFields fromFields(Fields fields) { |
| List<Integer> vals = new ArrayList<>(); |
| |
| BucketIterator iter = fields.getBucketIterator(); |
| while (iter.next()) { |
| vals.add(HashUtils.pairOfKeyAndVal(iter.getKey(), iter.getValue())); |
| } |
| Collections.sort( |
| vals, |
| new Comparator<Integer>() { |
| @Override |
| public int compare(Integer o1, Integer o2) { |
| return HashUtils.valOfPair(o2) - HashUtils.valOfPair(o1); |
| } |
| } |
| ); |
| |
| int[] theFields = new int[vals.size()]; |
| int count = 0; |
| for (Integer val : vals) { |
| theFields[count++] = val; |
| } |
| |
| return new OnHeapImmutableCompactFields(fields.getPreamble(), theFields); |
| } |
| |
| private final Preamble preamble; |
| private final int[] fields; |
| |
| OnHeapImmutableCompactFields(Preamble preamble, int[] fields) { |
| this.preamble = preamble; |
| this.fields = fields; |
| } |
| |
| @Override |
| public Preamble getPreamble() { |
| return preamble; |
| } |
| |
| @Override |
| public Fields updateBucket(int i, byte val, UpdateCallback cb) { |
| throw new UnsupportedOperationException("Cannot mutate a compact sketch"); |
| } |
| |
| @Override |
| public int intoByteArray(byte[] array, int offset) { |
| int numBytesNeeded = numBytesToSerialize(); |
| if (array.length - offset < numBytesNeeded) { |
| throw new IllegalArgumentException( |
| String.format("array too small[%,d] < [%,d]", array.length - offset, numBytesNeeded) |
| ); |
| } |
| |
| Memory mem = new NativeMemory(array); |
| mem.putByte(offset++, Fields.SORTED_SPARSE_VERSION); |
| |
| for (int field : fields) { |
| mem.putInt(offset, field); |
| offset += 4; |
| } |
| return offset; |
| } |
| |
| @Override |
| public int numBytesToSerialize() { |
| return 1 + (fields.length << 2); |
| } |
| |
| @Override |
| public Fields toCompact() { |
| return this; |
| } |
| |
| @Override |
| public BucketIterator getBucketIterator() { |
| return new BucketIterator() { |
| int i = -1; |
| |
| @Override |
| public boolean next() { |
| return ++i < fields.length; |
| } |
| |
| @Override |
| public int getKey() { |
| return HashUtils.keyOfPair(fields[i]); |
| } |
| |
| @Override |
| public byte getValue() { |
| return HashUtils.valOfPair(fields[i]); |
| } |
| }; |
| } |
| |
| @Override |
| public Fields unionInto(Fields recipient, UpdateCallback cb) { |
| return recipient.unionBucketIterator(getBucketIterator(), cb); |
| } |
| |
| @Override |
| public Fields unionBucketIterator(BucketIterator iter, UpdateCallback cb) { |
| throw new UnsupportedOperationException("Cannot mutate a compact sketch"); |
| } |
| |
| @Override |
| public Fields unionCompressedAndExceptions( |
| byte[] compressed, int minVal, OnHeapHash exceptions, UpdateCallback cb) { |
| throw new UnsupportedOperationException("Cannot mutate a compact sketch"); |
| } |
| } |