blob: 58fc84603ac1a3435ef08b60d375daaeeb99a8c4 [file] [log] [blame]
# 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.
#
import struct
from iotdb.utils.IoTDBConstants import TSDataType
from iotdb.utils.BitMap import BitMap
class Tablet(object):
def __init__(self, device_id, measurements, data_types, values, timestamps):
"""
creating a tablet for insertion
for example, considering device: root.sg1.d1
timestamps, m1, m2, m3
1, 125.3, True, text1
2, 111.6, False, text2
3, 688.6, True, text3
Notice: From 0.13.0, the tablet can contain empty cell
The tablet will be sorted at the initialization by timestamps
:param device_id: String, IoTDB time series path to device layer (without sensor)
:param measurements: List, sensors
:param data_types: TSDataType List, specify value types for sensors
:param values: 2-D List, the values of each row should be the outer list element
:param timestamps: List,
"""
if len(timestamps) != len(values):
raise RuntimeError(
"Input error! len(timestamps) does not equal to len(values)!"
)
if not Tablet.check_sorted(timestamps):
sorted_zipped = sorted(zip(timestamps, values))
result = zip(*sorted_zipped)
self.__timestamps, self.__values = [list(x) for x in result]
else:
self.__values = values
self.__timestamps = timestamps
self.__device_id = device_id
self.__measurements = measurements
self.__data_types = data_types
self.__row_number = len(timestamps)
self.__column_number = len(measurements)
@staticmethod
def check_sorted(timestamps):
for i in range(1, len(timestamps)):
if timestamps[i] < timestamps[i - 1]:
return False
return True
def get_measurements(self):
return self.__measurements
def get_data_types(self):
return self.__data_types
def get_row_number(self):
return self.__row_number
def get_device_id(self):
return self.__device_id
def get_binary_timestamps(self):
format_str_list = [">"]
values_tobe_packed = []
for timestamp in self.__timestamps:
format_str_list.append("q")
values_tobe_packed.append(timestamp)
format_str = "".join(format_str_list)
return struct.pack(format_str, *values_tobe_packed)
def get_binary_values(self):
format_str_list = [">"]
values_tobe_packed = []
bitmaps = []
has_none = False
for i in range(self.__column_number):
bitmap = None
bitmaps.append(bitmap)
if self.__data_types[i] == TSDataType.BOOLEAN:
format_str_list.append(str(self.__row_number))
format_str_list.append("?")
for j in range(self.__row_number):
if self.__values[j][i] is not None:
values_tobe_packed.append(self.__values[j][i])
else:
values_tobe_packed.append(False)
self.__mark_none_value(bitmaps, i, j)
has_none = True
elif self.__data_types[i] == TSDataType.INT32:
format_str_list.append(str(self.__row_number))
format_str_list.append("i")
for j in range(self.__row_number):
if self.__values[j][i] is not None:
values_tobe_packed.append(self.__values[j][i])
else:
values_tobe_packed.append(0)
self.__mark_none_value(bitmaps, i, j)
has_none = True
elif self.__data_types[i] == TSDataType.INT64:
format_str_list.append(str(self.__row_number))
format_str_list.append("q")
for j in range(self.__row_number):
if self.__values[j][i] is not None:
values_tobe_packed.append(self.__values[j][i])
else:
values_tobe_packed.append(0)
self.__mark_none_value(bitmaps, i, j)
has_none = True
elif self.__data_types[i] == TSDataType.FLOAT:
format_str_list.append(str(self.__row_number))
format_str_list.append("f")
for j in range(self.__row_number):
if self.__values[j][i] is not None:
values_tobe_packed.append(self.__values[j][i])
else:
values_tobe_packed.append(0)
self.__mark_none_value(bitmaps, i, j)
has_none = True
elif self.__data_types[i] == TSDataType.DOUBLE:
format_str_list.append(str(self.__row_number))
format_str_list.append("d")
for j in range(self.__row_number):
if self.__values[j][i] is not None:
values_tobe_packed.append(self.__values[j][i])
else:
values_tobe_packed.append(0)
self.__mark_none_value(bitmaps, i, j)
has_none = True
elif self.__data_types[i] == TSDataType.TEXT:
for j in range(self.__row_number):
if self.__values[j][i] is not None:
value_bytes = bytes(self.__values[j][i], "utf-8")
format_str_list.append("i")
format_str_list.append(str(len(value_bytes)))
format_str_list.append("s")
values_tobe_packed.append(len(value_bytes))
values_tobe_packed.append(value_bytes)
else:
value_bytes = bytes("", "utf-8")
format_str_list.append("i")
format_str_list.append(str(len(value_bytes)))
format_str_list.append("s")
values_tobe_packed.append(len(value_bytes))
values_tobe_packed.append(value_bytes)
self.__mark_none_value(bitmaps, i, j)
has_none = True
else:
raise RuntimeError("Unsupported data type:" + str(self.__data_types[i]))
if has_none:
for i in range(self.__column_number):
format_str_list.append("?")
if bitmaps[i] is None:
values_tobe_packed.append(False)
else:
values_tobe_packed.append(True)
format_str_list.append(str(self.__row_number // 8 + 1))
format_str_list.append("c")
for j in range(self.__row_number // 8 + 1):
values_tobe_packed.append(bytes([bitmaps[i].bits[j]]))
format_str = "".join(format_str_list)
return struct.pack(format_str, *values_tobe_packed)
def __mark_none_value(self, bitmaps, column, row):
if bitmaps[column] is None:
bitmaps[column] = BitMap(self.__row_number)
bitmaps[column].mark(row)