org.apache.flink.runtime.state.gemini.engine.page.compress.GCompressHeaderHelper Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.flink.runtime.state.gemini.engine.page.compress;
import org.apache.flink.runtime.state.gemini.engine.page.DataPage;
import org.apache.flink.runtime.state.gemini.engine.page.bmap.ByteBufferUtils;
import java.nio.ByteBuffer;
import static org.apache.flink.util.Preconditions.checkState;
/**
* ----------------------------------------------------------
* |=================== compressed page ====================|
* |compressed header | page header | compressed page data |
* ==========================================================
* for un compressed page the format is following:
* ----------------------------------------------------------
* |=================== un compressed page =================|
* | page header | compressed page data |
* ==========================================================
* When page is compressed, there will be a compress header before the page data,
* when page is not compressed, there will no compress header before the page data.
* Compress Header: length:16
* - DataPageType(1 bytes) when page is compressed, this byte will always be 127
* - version(2 bytes)
* - MAGIC_NUMBER(2 bytes) -- 4726
* - algorithmCode(1 bytes)
* - diskLength(4 bytes) optional, maybe empty
* - reserved space.
*/
public class GCompressHeaderHelper {
private static final long serialVersionUID = 1L;
public static final int LENGTH = 16;
public static final short CURRENT_VERSION = 1;
public static final short MAGIC_NUMBER = 4726;
private static final int COMPRESSED_DATAPAGE_TYPE_INDEX = 0;
private static final int VERSION_START_INDEX = COMPRESSED_DATAPAGE_TYPE_INDEX + Byte.BYTES;
private static final int MAGIC_NUMBER_START_INDEX = VERSION_START_INDEX + Short.BYTES;
private static final int ALGORITHM_CODE_START_INDEX = MAGIC_NUMBER_START_INDEX + Short.BYTES;
private static final int DISK_LENGTH_START_INDEX = ALGORITHM_CODE_START_INDEX + Byte.BYTES;
// we use 127 as a compress data page type.
private static final byte COMPRESSED_DATAPAGE_TYPE = DataPage.DataPageType.COMPRESS_HEADER.getCode();
public static void writeCompressedDataPageType(ByteBuffer byteBuffe) {
ByteBufferUtils.putByte(byteBuffe, COMPRESSED_DATAPAGE_TYPE_INDEX, COMPRESSED_DATAPAGE_TYPE);
}
public static void writeCompressVersion(ByteBuffer byteBuffer, short version) {
ByteBufferUtils.putShort(byteBuffer, VERSION_START_INDEX, version);
}
public static void writeMagicNumber(ByteBuffer byteBuffer, short magic) {
ByteBufferUtils.putShort(byteBuffer, MAGIC_NUMBER_START_INDEX, magic);
}
public static void writeAlgorithmCode(ByteBuffer byteBuffer, byte code) {
ByteBufferUtils.putByte(byteBuffer, ALGORITHM_CODE_START_INDEX, code);
}
public static void writeDiskLength(ByteBuffer byteBuffer, int diskLength) {
ByteBufferUtils.putInt(byteBuffer, DISK_LENGTH_START_INDEX, diskLength);
}
public static void checkMagicNumber(byte[] input) {
ByteBuffer bb = ByteBuffer.wrap(input);
checkMagicNumber(bb);
}
public static void checkMagicNumber(ByteBuffer buffer) {
short magic = buffer.getShort(MAGIC_NUMBER_START_INDEX);
checkState(magic == MAGIC_NUMBER, "Wrong magic number");
}
public static GCompressAlgorithm readCompressAlgorithm(byte[] input) {
return readCompressAlgorithm(ByteBuffer.wrap(input));
}
public static GCompressAlgorithm readCompressAlgorithm(ByteBuffer buffer) {
byte code = buffer.get(ALGORITHM_CODE_START_INDEX);
return GCompressAlgorithm.valueOf(code);
}
public static int readDiskLength(byte[] input) {
return readDiskLength(ByteBuffer.wrap(input));
}
public static int readDiskLength(ByteBuffer buffer) {
return buffer.getInt(DISK_LENGTH_START_INDEX);
}
public static short readCompressVersion(byte[] input) {
return readCompressVersion(ByteBuffer.wrap(input));
}
public static short readCompressVersion(ByteBuffer buffer) {
return buffer.getShort(VERSION_START_INDEX);
}
public static boolean isPageCompressed(byte[] input) {
return isPageCompressed(ByteBuffer.wrap(input));
}
public static boolean isPageCompressed(ByteBuffer byteBuffer) {
return COMPRESSED_DATAPAGE_TYPE == byteBuffer.get(COMPRESSED_DATAPAGE_TYPE_INDEX);
}
}