| /* |
| * 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.iotdb.tsfile.encoding.decoder; |
| |
| import org.apache.iotdb.tsfile.encoding.encoder.FloatEncoder; |
| import org.apache.iotdb.tsfile.exception.encoding.TsFileDecodingException; |
| import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType; |
| import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding; |
| import org.apache.iotdb.tsfile.utils.Binary; |
| import org.apache.iotdb.tsfile.utils.ReadWriteForEncodingUtils; |
| |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import java.io.IOException; |
| import java.nio.ByteBuffer; |
| |
| /** |
| * Decoder for float or double value using rle or two diff. For more info about encoding pattern, |
| * see{@link FloatEncoder} |
| */ |
| public class FloatDecoder extends Decoder { |
| |
| private static final Logger logger = LoggerFactory.getLogger(FloatDecoder.class); |
| private Decoder decoder; |
| |
| /** maxPointValue = 10^(maxPointNumber). maxPointNumber can be read from the stream. */ |
| private double maxPointValue; |
| |
| /** flag that indicates whether we have read maxPointNumber and calculated maxPointValue. */ |
| private boolean isMaxPointNumberRead; |
| |
| public FloatDecoder(TSEncoding encodingType, TSDataType dataType) { |
| super(encodingType); |
| if (encodingType == TSEncoding.RLE) { |
| if (dataType == TSDataType.FLOAT) { |
| decoder = new IntRleDecoder(); |
| logger.debug("tsfile-encoding FloatDecoder: init decoder using int-rle and float"); |
| } else if (dataType == TSDataType.DOUBLE) { |
| decoder = new LongRleDecoder(); |
| logger.debug("tsfile-encoding FloatDecoder: init decoder using long-rle and double"); |
| } else { |
| throw new TsFileDecodingException( |
| String.format("data type %s is not supported by FloatDecoder", dataType)); |
| } |
| } else if (encodingType == TSEncoding.TS_2DIFF) { |
| if (dataType == TSDataType.FLOAT) { |
| decoder = new DeltaBinaryDecoder.IntDeltaDecoder(); |
| logger.debug("tsfile-encoding FloatDecoder: init decoder using int-delta and float"); |
| } else if (dataType == TSDataType.DOUBLE) { |
| decoder = new DeltaBinaryDecoder.LongDeltaDecoder(); |
| logger.debug("tsfile-encoding FloatDecoder: init decoder using long-delta and double"); |
| } else { |
| throw new TsFileDecodingException( |
| String.format("data type %s is not supported by FloatDecoder", dataType)); |
| } |
| } else { |
| throw new TsFileDecodingException( |
| String.format("%s encoding is not supported by FloatDecoder", encodingType)); |
| } |
| isMaxPointNumberRead = false; |
| } |
| |
| @Override |
| public float readFloat(ByteBuffer buffer) { |
| readMaxPointValue(buffer); |
| int value = decoder.readInt(buffer); |
| double result = value / maxPointValue; |
| return (float) result; |
| } |
| |
| @Override |
| public double readDouble(ByteBuffer buffer) { |
| readMaxPointValue(buffer); |
| long value = decoder.readLong(buffer); |
| return value / maxPointValue; |
| } |
| |
| private void readMaxPointValue(ByteBuffer buffer) { |
| if (!isMaxPointNumberRead) { |
| int maxPointNumber = ReadWriteForEncodingUtils.readUnsignedVarInt(buffer); |
| if (maxPointNumber <= 0) { |
| maxPointValue = 1; |
| } else { |
| maxPointValue = Math.pow(10, maxPointNumber); |
| } |
| isMaxPointNumberRead = true; |
| } |
| } |
| |
| @Override |
| public boolean hasNext(ByteBuffer buffer) throws IOException { |
| if (decoder == null) { |
| return false; |
| } |
| return decoder.hasNext(buffer); |
| } |
| |
| @Override |
| public Binary readBinary(ByteBuffer buffer) { |
| throw new TsFileDecodingException("Method readBinary is not supported by FloatDecoder"); |
| } |
| |
| @Override |
| public boolean readBoolean(ByteBuffer buffer) { |
| throw new TsFileDecodingException("Method readBoolean is not supported by FloatDecoder"); |
| } |
| |
| @Override |
| public short readShort(ByteBuffer buffer) { |
| throw new TsFileDecodingException("Method readShort is not supported by FloatDecoder"); |
| } |
| |
| @Override |
| public int readInt(ByteBuffer buffer) { |
| throw new TsFileDecodingException("Method readInt is not supported by FloatDecoder"); |
| } |
| |
| @Override |
| public long readLong(ByteBuffer buffer) { |
| throw new TsFileDecodingException("Method readLong is not supported by FloatDecoder"); |
| } |
| |
| @Override |
| public void reset() { |
| this.decoder.reset(); |
| this.isMaxPointNumberRead = false; |
| } |
| } |