tsfile_writer/writer/
mod.rs

1//! This is a not yet feature complete Writer for TsFiles Version 3 (as defined from the Apache IoTDB Project).
2//! Currently not all features of TsFiles are supported.
3//! Most notably:
4//!
5//! * No Aligned Chunks can be written
6//! * Not all Encodings are available
7//! * Not all DataTypes are supported
8//! * Not all Compression Types are supported
9//!
10//! But generally, the TsFiles written with this client are 100% compatible with TsFiles written in Java.
11//!
12//! ## Quickstart
13//!
14//! To write a TsFile just do something like
15//!
16//! ```
17//! use tsfile_writer::writer::tsfile_writer::TsFileWriter;
18//! use tsfile_writer::writer::IoTDBValue;
19//! use tsfile_writer::writer::tsfile_writer::DataPoint;
20//! use tsfile_writer::writer::schema::TsFileSchemaBuilder;
21//! use tsfile_writer::writer::schema::DeviceBuilder;
22//! use tsfile_writer::writer::TSDataType;
23//! use tsfile_writer::writer::encoding::TSEncoding;
24//! use tsfile_writer::writer::compression::CompressionType;
25//!
26//! // Create the Schema
27//! // Two devices with two sensors each
28//! let schema = TsFileSchemaBuilder::new()
29//!         .add(
30//!             "d1",
31//!             DeviceBuilder::new()
32//!                 .add(
33//!                     "s1",
34//!                     TSDataType::INT64,
35//!                     TSEncoding::PLAIN,
36//!                     CompressionType::UNCOMPRESSED,
37//!                 )
38//!                 .add(
39//!                     "s2",
40//!                     TSDataType::FLOAT,
41//!                     TSEncoding::PLAIN,
42//!                     CompressionType::UNCOMPRESSED,
43//!                 )
44//!                 .build(),
45//!         )
46//!         .add(
47//!             "d2",
48//!             DeviceBuilder::new()
49//!                 .add(
50//!                     "s1",
51//!                     TSDataType::INT64,
52//!                     TSEncoding::PLAIN,
53//!                     CompressionType::UNCOMPRESSED,
54//!                 )
55//!                 .add(
56//!                     "s2",
57//!                     TSDataType::FLOAT,
58//!                     TSEncoding::PLAIN,
59//!                     CompressionType::UNCOMPRESSED,
60//!                 )
61//!                 .build(),
62//!         )
63//!         .build();
64//!
65//! // Create the writer
66//! let mut writer = TsFileWriter::new(
67//!     "target/benchmark2.tsfile",
68//!     schema,
69//!     Default::default(),
70//! )
71//! .unwrap();
72//!
73//! // Write multiple timeseries at once
74//! writer.write_many("d1",1, vec![
75//!         DataPoint::new("s1", IoTDBValue::LONG(13)),
76//!         DataPoint::new("s2", IoTDBValue::FLOAT(13.0 as f32)),
77//! ]);
78//!
79//! // Write single series
80//! writer.write("d2", "s1", 1, IoTDBValue::LONG(14));
81//! writer.write("d2", "s2", 1, IoTDBValue::FLOAT(14.0 as f32));
82//! ```
83#![allow(unused_must_use)]
84extern crate core;
85
86use std::cmp::Ordering;
87use std::collections::hash_map::IntoIter;
88use std::collections::{BTreeMap, HashMap};
89use std::fmt::{Display, Formatter};
90use std::hash::Hash;
91use std::io::Write;
92use std::{io, vec};
93
94mod chunk_writer;
95pub mod compression;
96pub mod encoding;
97pub mod errors;
98mod group_writer;
99mod murmur128;
100pub mod schema;
101mod statistics;
102mod test;
103pub mod test_utils;
104pub mod ts_file_config;
105mod tsfile_io_writer;
106pub mod tsfile_writer;
107mod utils;
108
109use crate::writer::chunk_writer::ChunkMetadata;
110use crate::writer::compression::CompressionType;
111use crate::writer::encoding::TSEncoding;
112use crate::writer::errors::TsFileError;
113
114use crate::writer::murmur128::Murmur128;
115use crate::writer::schema::{DeviceBuilder, TsFileSchemaBuilder};
116use crate::writer::statistics::Statistics;
117use crate::writer::ts_file_config::TsFileConfig;
118use crate::writer::utils::{write_var_i32, write_var_u32};
119use crate::writer::MetadataIndexNodeType::LeafDevice;
120
121/// Central enum to pass Values to the writer
122#[allow(dead_code)]
123#[derive(Clone)]
124pub enum IoTDBValue {
125    DOUBLE(f64),
126    FLOAT(f32),
127    INT(i32),
128    LONG(i64),
129}
130
131impl From<i64> for IoTDBValue {
132    fn from(x: i64) -> Self {
133        IoTDBValue::LONG(x)
134    }
135}
136
137/// Extension of the Write trait
138/// that allows to get the position of the "buffer"
139/// via the `get_position()` method
140pub trait PositionedWrite: Write {
141    fn get_position(&self) -> u64;
142}
143
144pub struct WriteWrapper<T: Write> {
145    position: u64,
146    writer: T,
147}
148
149impl<T: Write> Write for WriteWrapper<T> {
150    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
151        match self.writer.write(buf) {
152            Ok(size) => {
153                self.position += size as u64;
154                Ok(size)
155            }
156            Err(e) => Err(e),
157        }
158    }
159
160    fn flush(&mut self) -> io::Result<()> {
161        self.writer.flush()
162    }
163}
164
165impl<T: Write> PositionedWrite for WriteWrapper<T> {
166    fn get_position(&self) -> u64 {
167        self.position
168    }
169}
170
171impl<T: Write> WriteWrapper<T> {
172    fn new(writer: T) -> WriteWrapper<T> {
173        WriteWrapper {
174            position: 0,
175            writer,
176        }
177    }
178}
179
180impl PositionedWrite for Vec<u8> {
181    fn get_position(&self) -> u64 {
182        self.len() as u64
183    }
184}
185
186#[derive(Copy, Clone, Eq, PartialEq, Debug)]
187pub enum TSDataType {
188    INT32,
189    INT64,
190    FLOAT,
191}
192
193impl TSDataType {
194    pub fn serialize(&self) -> u8 {
195        match self {
196            TSDataType::INT32 => 1,
197            TSDataType::INT64 => 2,
198            TSDataType::FLOAT => 3,
199        }
200    }
201}
202
203impl TryFrom<u8> for TSDataType {
204    type Error = ();
205
206    fn try_from(value: u8) -> Result<Self, Self::Error> {
207        match value {
208            1 => Ok(TSDataType::INT32),
209            2 => Ok(TSDataType::INT64),
210            3 => Ok(TSDataType::FLOAT),
211            _ => Err(()),
212        }
213    }
214}
215
216#[derive(Clone)]
217pub struct MeasurementSchema {
218    pub data_type: TSDataType,
219    pub encoding: TSEncoding,
220    pub compression: CompressionType,
221}
222
223#[derive(Clone, PartialEq, Eq, Hash)]
224struct Path {
225    path: String,
226}
227
228impl Display for Path {
229    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
230        write!(f, "{}", self.path)
231    }
232}
233
234impl Ord for Path {
235    fn cmp(&self, other: &Self) -> Ordering {
236        self.path.cmp(&other.path)
237    }
238}
239
240impl PartialOrd<Self> for Path {
241    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
242        self.path.partial_cmp(&other.path)
243    }
244}
245
246impl MeasurementSchema {
247    #[allow(dead_code)]
248    fn new(
249        data_type: TSDataType,
250        encoding: TSEncoding,
251        compression: CompressionType,
252    ) -> MeasurementSchema {
253        MeasurementSchema {
254            data_type,
255            encoding,
256            compression,
257        }
258    }
259}
260
261#[derive(Clone)]
262pub struct MeasurementGroup<'a> {
263    measurement_schemas: HashMap<&'a str, MeasurementSchema>,
264}
265
266impl<'a> MeasurementGroup<'a> {
267    pub fn get_timeseries(&self) -> IntoIter<&'a str, MeasurementSchema> {
268        self.measurement_schemas.clone().into_iter()
269    }
270}
271
272#[derive(Clone)]
273pub struct Schema<'a> {
274    measurement_groups: HashMap<&'a str, MeasurementGroup<'a>>,
275}
276
277impl<'a> Schema<'a> {
278    pub fn get_devices(&self) -> IntoIter<&'a str, MeasurementGroup<'a>> {
279        self.measurement_groups.clone().into_iter()
280    }
281}
282
283impl<'a> Display for Schema<'a> {
284    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
285        let mut devices = vec![];
286        for device_id in self.measurement_groups.keys() {
287            devices.push(device_id);
288        }
289        write!(f, "{:?}", devices)
290    }
291}
292
293impl<'a> Schema<'a> {
294    pub fn simple(
295        device_id: &'a str,
296        measurement_id: &'a str,
297        data_type: TSDataType,
298        encoding: TSEncoding,
299        compression: CompressionType,
300    ) -> Schema<'a> {
301        TsFileSchemaBuilder::new()
302            .add(
303                device_id,
304                DeviceBuilder::new()
305                    .add(measurement_id, data_type, encoding, compression)
306                    .build(),
307            )
308            .build()
309    }
310}
311
312struct ChunkGroupMetadata {
313    device_id: String,
314    chunk_metadata: Vec<ChunkMetadata>,
315}
316
317impl ChunkGroupMetadata {
318    fn new(device_id: String, chunk_metadata: Vec<ChunkMetadata>) -> ChunkGroupMetadata {
319        ChunkGroupMetadata {
320            device_id,
321            chunk_metadata,
322        }
323    }
324}
325
326#[derive(Clone)]
327enum MetadataIndexNodeType {
328    LeafMeasurement,
329    InternalMeasurement,
330    LeafDevice,
331}
332
333impl Serializable for MetadataIndexNodeType {
334    //   /** INTERNAL_DEVICE */
335    //   INTERNAL_DEVICE((byte) 0),
336    //
337    //   /** LEAF_DEVICE */
338    //   LEAF_DEVICE((byte) 1),
339    //
340    //   /** INTERNAL_MEASUREMENT */
341    //   INTERNAL_MEASUREMENT((byte) 2),
342    //
343    //   /** INTERNAL_MEASUREMENT */
344    //   LEAF_MEASUREMENT((byte) 3);
345    fn serialize(&self, file: &mut dyn PositionedWrite) -> Result<(), TsFileError> {
346        let byte: u8 = match self {
347            MetadataIndexNodeType::LeafMeasurement => 0x03,
348            MetadataIndexNodeType::InternalMeasurement => 0x02,
349            LeafDevice => 0x01,
350        };
351        file.write(&[byte]);
352
353        Ok(())
354    }
355}
356
357struct TimeseriesMetadata {}
358
359#[derive(Clone)]
360struct MetadataIndexEntry {
361    name: String,
362    offset: usize,
363}
364
365impl Serializable for MetadataIndexEntry {
366    fn serialize(&self, file: &mut dyn PositionedWrite) -> Result<(), TsFileError> {
367        // int byteLen = 0;
368        // byteLen += ReadWriteIOUtils.writeVar(name, outputStream);
369        // byteLen += ReadWriteIOUtils.write(offset, outputStream);
370        // return byteLen;
371        write_str(file, self.name.as_str());
372        file.write(&self.offset.to_be_bytes());
373        // file.write(&(self.offset as i64).to_be_bytes());
374
375        Ok(())
376    }
377}
378
379#[derive(Clone)]
380struct MetadataIndexNode {
381    children: Vec<MetadataIndexEntry>,
382    end_offset: usize,
383    node_type: MetadataIndexNodeType,
384}
385
386impl Serializable for MetadataIndexNode {
387    fn serialize(&self, file: &mut dyn PositionedWrite) -> Result<(), TsFileError> {
388        // int byteLen = 0;
389        // byteLen += ReadWriteForEncodingUtils.writeUnsignedVarInt(children.size(), outputStream);
390        // for (MetadataIndexEntry metadataIndexEntry : children) {
391        //   byteLen += metadataIndexEntry.serializeTo(outputStream);
392        // }
393        // byteLen += ReadWriteIOUtils.write(endOffset, outputStream);
394        // byteLen += ReadWriteIOUtils.write(nodeType.serialize(), outputStream);
395        // return byteLen;
396        write_var_u32(self.children.len() as u32, file);
397
398        for metadata_index_entry in self.children.iter() {
399            metadata_index_entry.serialize(file);
400        }
401
402        file.write(&self.end_offset.to_be_bytes());
403        self.node_type.serialize(file);
404
405        Ok(())
406    }
407}
408
409impl MetadataIndexNode {
410    fn new(node_type: MetadataIndexNodeType) -> MetadataIndexNode {
411        MetadataIndexNode {
412            children: vec![],
413            end_offset: 0,
414            node_type,
415        }
416    }
417
418    fn add_current_index_node_to_queue(
419        current_index_node: &mut MetadataIndexNode,
420        measurement_metadata_index_queue: &mut Vec<MetadataIndexNode>,
421        file: &mut dyn PositionedWrite,
422    ) {
423        // TODO file.getPosition
424        // currentIndexNode.setEndOffset(out.getPosition());
425        current_index_node.end_offset = file.get_position() as usize;
426        // metadataIndexNodeQueue.add(currentIndexNode);
427        measurement_metadata_index_queue.push(current_index_node.clone());
428    }
429
430    #[allow(unused_variables)]
431    fn generate_root_node(
432        mut measurement_metadata_index_queue: Vec<MetadataIndexNode>,
433        file: &mut dyn PositionedWrite,
434        node_type: MetadataIndexNodeType,
435        config: &TsFileConfig,
436    ) -> MetadataIndexNode {
437        // int queueSize = metadataIndexNodeQueue.size();
438        // MetadataIndexNode metadataIndexNode;
439        // MetadataIndexNode currentIndexNode = new MetadataIndexNode(type);
440        // while (queueSize != 1) {
441        //   for (int i = 0; i < queueSize; i++) {
442        //     metadataIndexNode = metadataIndexNodeQueue.poll();
443        //     // when constructing from internal node, each node is related to an entry
444        //     if (currentIndexNode.isFull()) {
445        //       addCurrentIndexNodeToQueue(currentIndexNode, metadataIndexNodeQueue, out);
446        //       currentIndexNode = new MetadataIndexNode(type);
447        //     }
448        //     currentIndexNode.addEntry(
449        //         new MetadataIndexEntry(metadataIndexNode.peek().getName(), out.getPosition()));
450        //     metadataIndexNode.serializeTo(out.wrapAsStream());
451        //   }
452        //   addCurrentIndexNodeToQueue(currentIndexNode, metadataIndexNodeQueue, out);
453        //   currentIndexNode = new MetadataIndexNode(type);
454        //   queueSize = metadataIndexNodeQueue.size();
455        // }
456        // return metadataIndexNodeQueue.poll();
457        // TODO
458        let mut queue_size = measurement_metadata_index_queue.len();
459        let mut metadata_index_node;
460        let mut current_index_metadata = MetadataIndexNode::new(node_type.clone());
461
462        while queue_size != 1 {
463            for i in 0..queue_size {
464                metadata_index_node = measurement_metadata_index_queue.last().unwrap().clone();
465                let device = match metadata_index_node.children.get(0) {
466                    None => {
467                        panic!("...")
468                    }
469                    Some(inner) => inner.name.clone(),
470                };
471                measurement_metadata_index_queue.remove(measurement_metadata_index_queue.len() - 1);
472                if current_index_metadata.is_full(config) {
473                    current_index_metadata.end_offset = file.get_position() as usize;
474                    measurement_metadata_index_queue.push(current_index_metadata.clone());
475                }
476                // ...
477                let name = match metadata_index_node.children.get(0) {
478                    None => {
479                        panic!("This should not happen!")
480                    }
481                    Some(node) => node.name.clone(),
482                };
483                current_index_metadata.children.push(MetadataIndexEntry {
484                    name,
485                    offset: file.get_position() as usize,
486                });
487            }
488            // ...
489            Self::add_current_index_node_to_queue(
490                &mut current_index_metadata,
491                &mut measurement_metadata_index_queue,
492                file,
493            );
494            current_index_metadata = MetadataIndexNode {
495                children: vec![],
496                end_offset: 0,
497                node_type: node_type.clone(),
498            };
499            queue_size = measurement_metadata_index_queue.len();
500        }
501        return measurement_metadata_index_queue.get(0).unwrap().clone();
502    }
503
504    #[allow(unused_variables)]
505    fn construct_metadata_index(
506        device_timeseries_metadata_map: &BTreeMap<String, Vec<Box<dyn TimeSeriesMetadatable>>>,
507        file: &mut dyn PositionedWrite,
508        config: &TsFileConfig,
509    ) -> MetadataIndexNode {
510        let mut device_metadata_index_map: HashMap<String, MetadataIndexNode> = HashMap::new();
511
512        for (device, list_metadata) in device_timeseries_metadata_map.iter() {
513            if list_metadata.is_empty() {
514                continue;
515            }
516
517            let mut measurement_metadata_index_queue: Vec<MetadataIndexNode> = vec![];
518
519            let timeseries_metadata: TimeseriesMetadata;
520            let mut current_index_node: MetadataIndexNode =
521                MetadataIndexNode::new(MetadataIndexNodeType::LeafMeasurement);
522
523            // for (int i = 0; i < entry.getValue().size(); i++) {
524            for i in 0..list_metadata.len() {
525                let timeseries_metadata = list_metadata.get(i).unwrap();
526
527                if i % config.max_degree_of_index_node == 0 {
528                    if current_index_node.is_full(config) {
529                        Self::add_current_index_node_to_queue(
530                            &mut current_index_node,
531                            &mut measurement_metadata_index_queue,
532                            file,
533                        );
534                        current_index_node =
535                            MetadataIndexNode::new(MetadataIndexNodeType::LeafMeasurement);
536                    }
537                    current_index_node.children.push(MetadataIndexEntry {
538                        name: timeseries_metadata.get_measurement_id(),
539                        offset: file.get_position() as usize,
540                    });
541                }
542                timeseries_metadata.serialize(file);
543            }
544            // addCurrentIndexNodeToQueue(currentIndexNode, measurementMetadataIndexQueue, out);
545            // deviceMetadataIndexMap.put(
546            //       entry.getKey(),
547            //       generateRootNode(
548            //           measurementMetadataIndexQueue, out, MetadataIndexNodeType.INTERNAL_MEASUREMENT));
549            current_index_node.end_offset = file.get_position() as usize;
550            measurement_metadata_index_queue.push(current_index_node.clone());
551
552            let root_node = Self::generate_root_node(
553                measurement_metadata_index_queue,
554                file,
555                MetadataIndexNodeType::InternalMeasurement,
556                config,
557            );
558            device_metadata_index_map.insert(device.clone(), root_node);
559        }
560
561        if device_metadata_index_map.len() <= config.max_degree_of_index_node {
562            let mut metadata_index_node = MetadataIndexNode::new(LeafDevice);
563
564            for (s, value) in device_metadata_index_map {
565                metadata_index_node.children.push(MetadataIndexEntry {
566                    name: s.to_owned(),
567                    offset: file.get_position() as usize,
568                });
569                value.serialize(file);
570            }
571            metadata_index_node.end_offset = file.get_position() as usize;
572            return metadata_index_node;
573        }
574
575        panic!("This is not yet implemented!");
576
577        // // if not exceed the max child nodes num, ignore the device index and directly point to the
578        // // measurement
579        // if (deviceMetadataIndexMap.size() <= config.getMaxDegreeOfIndexNode()) {
580        //   MetadataIndexNode metadataIndexNode =
581        //       new MetadataIndexNode(MetadataIndexNodeType.LEAF_DEVICE);
582        //   for (Map.Entry<String, MetadataIndexNode> entry : deviceMetadataIndexMap.entrySet()) {
583        //     metadataIndexNode.addEntry(new MetadataIndexEntry(entry.getKey(), out.getPosition()));
584        //     entry.getValue().serializeTo(out.wrapAsStream());
585        //   }
586        //   metadataIndexNode.setEndOffset(out.getPosition());
587        //   return metadataIndexNode;
588        // }
589        //
590        // // else, build level index for devices
591        // Queue<MetadataIndexNode> deviceMetadataIndexQueue = new ArrayDeque<>();
592        // MetadataIndexNode currentIndexNode = new MetadataIndexNode(MetadataIndexNodeType.LEAF_DEVICE);
593        //
594        // for (Map.Entry<String, MetadataIndexNode> entry : deviceMetadataIndexMap.entrySet()) {
595        //   // when constructing from internal node, each node is related to an entry
596        //   if (currentIndexNode.isFull()) {
597        //     addCurrentIndexNodeToQueue(currentIndexNode, deviceMetadataIndexQueue, out);
598        //     currentIndexNode = new MetadataIndexNode(MetadataIndexNodeType.LEAF_DEVICE);
599        //   }
600        //   currentIndexNode.addEntry(new MetadataIndexEntry(entry.getKey(), out.getPosition()));
601        //   entry.getValue().serializeTo(out.wrapAsStream());
602        // }
603        // addCurrentIndexNodeToQueue(currentIndexNode, deviceMetadataIndexQueue, out);
604        // MetadataIndexNode deviceMetadataIndexNode =
605        //     generateRootNode(deviceMetadataIndexQueue, out, MetadataIndexNodeType.INTERNAL_DEVICE);
606        // deviceMetadataIndexNode.setEndOffset(out.getPosition());
607        // return deviceMetadataIndexNode;
608    }
609    fn is_full(&self, config: &TsFileConfig) -> bool {
610        self.children.len() >= config.max_degree_of_index_node
611    }
612}
613
614trait TimeSeriesMetadatable {
615    fn get_measurement_id(&self) -> String;
616    fn serialize(&self, file: &mut dyn PositionedWrite) -> io::Result<()>;
617}
618
619impl TimeSeriesMetadatable for TimeSeriesMetadata {
620    fn get_measurement_id(&self) -> String {
621        self.measurement_id.clone()
622    }
623
624    fn serialize(&self, file: &mut dyn PositionedWrite) -> io::Result<()> {
625        file.write_all(&[self.time_series_metadata_type]);
626        write_str(file, self.measurement_id.as_str());
627        file.write_all(&[self.data_type.serialize()]);
628        write_var_u32(self.chunk_meta_data_list_data_size as u32, file);
629        self.statistics.serialize(file);
630        file.write_all(&self.buffer);
631        Ok(())
632    }
633}
634
635struct TimeSeriesMetadata {
636    time_series_metadata_type: u8,
637    chunk_meta_data_list_data_size: usize,
638    measurement_id: String,
639    data_type: TSDataType,
640    statistics: Statistics,
641    buffer: Vec<u8>,
642}
643//
644// impl<T> Serializable for TimeSeriesMetadata<T> {
645//     fn serialize(&self, file: &mut dyn PositionedWrite) -> io::Result<()> {
646//         file.write_all(&[self.time_series_metadata_type]);
647//         write_str(file, self.measurement_id.as_str());
648//         file.write_all(&[self.data_type.serialize()]);
649//         write_var_u32(self.chunk_meta_data_list_data_size as u32, file);
650//         self.statistics.serialize(file);
651//         file.write_all(&self.buffer);
652//         Ok(())
653//     }
654// }
655
656struct HashFunction {
657    cap: i32,
658    seed: i32,
659}
660
661impl HashFunction {
662    fn new(cap: i32, seed: i32) -> HashFunction {
663        HashFunction { cap, seed }
664    }
665
666    fn _murmur_hash(&self, s: &str, seed: i32) -> i32 {
667        Murmur128::hash(s, seed)
668    }
669
670    fn hash(&self, value: &str) -> usize {
671        // return Math.abs(Murmur128Hash.hash(value, seed)) % cap;
672        (self._murmur_hash(value, self.seed).abs() % self.cap) as usize
673    }
674}
675
676struct BloomFilter {
677    size: i32,
678    hash_function_size: i32,
679    func: Vec<HashFunction>,
680    bit_set: Vec<bool>,
681}
682
683impl BloomFilter {
684    fn add(&mut self, path: String) {
685        for f in self.func.iter() {
686            let bit_id = f.hash(&path);
687            // println!("{path} - {} -> {}", f.seed, bit_id);
688            self.bit_set[bit_id] = true;
689        }
690    }
691
692    fn new(size: i32, hash_function_size: i32, config: &TsFileConfig) -> BloomFilter {
693        let mut func = vec![];
694
695        for i in 0..hash_function_size {
696            func.push(HashFunction::new(size, config.seeds[i as usize] as i32));
697        }
698
699        let bit_set = vec![false; size as usize];
700
701        BloomFilter {
702            size,
703            hash_function_size,
704            func,
705            bit_set,
706        }
707    }
708
709    fn build(paths: Vec<Path>, config: &TsFileConfig) -> BloomFilter {
710        let mut filter =
711            BloomFilter::empty_filter(config.bloom_filter_error_rate, paths.len() as i32, config);
712
713        for path in paths {
714            filter.add(path.path);
715        }
716
717        filter
718    }
719
720    fn empty_filter(error_percent: f64, num_of_string: i32, config: &TsFileConfig) -> BloomFilter {
721        let mut error = error_percent;
722        error = error.max(config.min_bloom_filter_error_rate);
723        error = error.min(config.max_bloom_filter_error_rate);
724
725        let ln2 = 2.0_f64.ln();
726
727        let size = (-num_of_string as f64 * error.ln() / ln2 / ln2) as i32 + 1;
728        let hash_function_size = ((-1.0 * error.ln() / ln2) + 1.0) as i32;
729
730        BloomFilter::new(
731            size.max(config.minimal_size),
732            hash_function_size.min(config.maximal_hash_function_size),
733            config,
734        )
735    }
736
737    fn serialize_bits(&self) -> Vec<u8> {
738        let number_of_bytes = if self.bit_set.len() % 8 == 0 {
739            self.bit_set.len() / 8
740        } else {
741            (self.bit_set.len() + (self.bit_set.len() % 8)) / 8
742        };
743
744        let mut result = vec![0_u8; number_of_bytes];
745
746        for i in 0..self.bit_set.len() {
747            let byte_index = (i - (i % 8)) / 8;
748            let bit_index = i % 8;
749
750            // println!("{} - {} / {} -> {}", i, byte_index, bit_index, self.bit_set[i]);
751
752            // TODO why is this necessary?
753            // if byte_index >= result.len() {
754            //     println!("Skipped!!!!");
755            //     continue;
756            // }
757
758            let value = *result.get(byte_index).unwrap();
759
760            // See https://stackoverflow.com/questions/57449264/how-to-get-replace-a-value-in-rust-vec
761            let bit: u8 = if self.bit_set[i] { 0x01 } else { 0x00 };
762            std::mem::replace(&mut result[byte_index], value | (bit << bit_index));
763        }
764
765        // Remove all trailing zero-bytes
766        while result.last().is_some() && *result.last().unwrap() == 0x00 {
767            result.remove(result.len() - 1);
768        }
769
770        result
771    }
772}
773
774impl Serializable for BloomFilter {
775    fn serialize(&self, file: &mut dyn PositionedWrite) -> Result<(), TsFileError> {
776        // Real
777        let bytes = self.serialize_bits();
778
779        write_var_u32(bytes.len() as u32, file);
780        file.write_all(bytes.as_slice());
781        write_var_u32(self.size as u32, file);
782        write_var_u32(self.hash_function_size as u32, file);
783
784        Ok(())
785    }
786}
787
788struct TsFileMetadata {
789    metadata_index: Option<MetadataIndexNode>,
790    meta_offset: u64,
791}
792
793impl TsFileMetadata {
794    pub fn new(metadata_index: Option<MetadataIndexNode>, meta_offset: u64) -> TsFileMetadata {
795        TsFileMetadata {
796            metadata_index,
797            meta_offset,
798        }
799    }
800}
801
802impl Serializable for TsFileMetadata {
803    fn serialize(&self, file: &mut dyn PositionedWrite) -> Result<(), TsFileError> {
804        match self.metadata_index.clone() {
805            Some(index) => {
806                index.serialize(file);
807            }
808            None => {
809                // Write 0 as 4 bytes (u32)
810                file.write_all(&0x00_u32.to_be_bytes());
811            }
812        }
813        // Meta Offset
814        file.write_all(&self.meta_offset.to_be_bytes());
815
816        Ok(())
817    }
818}
819
820pub struct ChunkGroupHeader<'a> {
821    device_id: &'a str,
822}
823
824impl<'a> ChunkGroupHeader<'a> {
825    fn new(device_id: &'a str) -> ChunkGroupHeader<'a> {
826        ChunkGroupHeader { device_id }
827    }
828}
829
830impl Serializable for ChunkGroupHeader<'_> {
831    fn serialize(&self, file: &mut dyn PositionedWrite) -> Result<(), TsFileError> {
832        file.write_all(&[0])?;
833        write_str(file, self.device_id)?;
834        Ok(())
835    }
836}
837
838struct ChunkGroup<'a> {
839    header: ChunkGroupHeader<'a>,
840}
841
842impl Serializable for ChunkGroup<'_> {
843    fn serialize(&self, file: &mut dyn PositionedWrite) -> Result<(), TsFileError> {
844        self.header.serialize(file)
845    }
846}
847
848pub trait Serializable {
849    fn serialize(&self, file: &mut dyn PositionedWrite) -> Result<(), TsFileError>;
850}
851
852fn write_str(file: &mut dyn PositionedWrite, s: &str) -> Result<(), TsFileError> {
853    let len = s.len() as i32;
854    write_var_i32(len, file)?;
855    let bytes = s.as_bytes();
856    file.write_all(bytes)?; // measurement id
857    Ok(())
858}
859
860#[cfg(test)]
861mod tests {
862    use std::collections::HashMap;
863    use std::time::{SystemTime, UNIX_EPOCH};
864
865    use crate::writer::compression::CompressionType;
866    use crate::writer::encoding::TSEncoding;
867    use crate::writer::schema::{DeviceBuilder, TsFileSchemaBuilder};
868    use crate::writer::tsfile_writer::TsFileWriter;
869    use crate::writer::utils::{read_var_u32, write_var_u32};
870    use crate::writer::{
871        IoTDBValue, MeasurementGroup, MeasurementSchema, Schema, TSDataType, TsFileError,
872        WriteWrapper,
873    };
874
875    #[test]
876    fn it_works() {
877        let result = 2 + 2;
878        assert_eq!(result, 4);
879    }
880
881    #[test]
882    fn write_file_test_4() {
883        let expectation = [
884            0x54, 0x73, 0x46, 0x69, 0x6C, 0x65, 0x03, 0x00, 0x04, 0x64, 0x31, 0x05, 0x04, 0x73,
885            0x31, 0x20, 0x01, 0x00, 0x00, 0x1E, 0x1E, 0x1A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
886            0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00,
887            0x00, 0x00, 0x00, 0x01, 0x01, 0x44, 0x1A, 0x1C, 0x1E, // TODO make this in HEX
888            2, 0, 4, 115, 49, 1, 8, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0,
889            13, 0, 0, 0, 15, 0, 0, 0, 13, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0,
890            0, 11, 1, 4, 115, 49, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 107, 3, 1, 4, 100,
891            49, 0, 0, 0, 0, 0, 0, 0, 107, 0, 0, 0, 0, 0, 0, 0, 128, 1, 0, 0, 0, 0, 0, 0, 0, 51, 31,
892            4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0,
893            0, 2, 128, 2, 5, 0, 0, 0, 64, 84, 115, 70, 105, 108, 101,
894        ];
895
896        let measurement_schema = MeasurementSchema::new(
897            TSDataType::INT32,
898            TSEncoding::PLAIN,
899            CompressionType::UNCOMPRESSED,
900        );
901
902        let mut measurement_schema_map = HashMap::new();
903        measurement_schema_map.insert("s1", measurement_schema);
904        let measurement_group = MeasurementGroup {
905            measurement_schemas: measurement_schema_map,
906        };
907        let mut measurement_groups_map = HashMap::new();
908        let d1 = "d1";
909        measurement_groups_map.insert(d1, measurement_group);
910        let schema = Schema {
911            measurement_groups: measurement_groups_map,
912        };
913        let buffer: Vec<u8> = vec![];
914        let buffer_writer = WriteWrapper::new(buffer);
915
916        let mut writer =
917            TsFileWriter::new_from_writer(schema, buffer_writer, Default::default()).unwrap();
918
919        TsFileWriter::write(&mut writer, "d1", "s1", 1, IoTDBValue::INT(13));
920        TsFileWriter::write(&mut writer, "d1", "s1", 10, IoTDBValue::INT(14));
921        TsFileWriter::write(&mut writer, "d1", "s1", 100, IoTDBValue::INT(15));
922
923        writer.close();
924
925        let buffer_writer = writer.file_io_writer.out;
926
927        assert_eq!(buffer_writer.writer, expectation);
928        assert_eq!(buffer_writer.position, expectation.len() as u64);
929    }
930
931    #[test]
932    fn write_file_5() {
933        let device = "root.sg.d1";
934        let schema = TsFileSchemaBuilder::new()
935            .add(
936                device,
937                DeviceBuilder::new()
938                    .add(
939                        "s1",
940                        TSDataType::INT32,
941                        TSEncoding::PLAIN,
942                        CompressionType::UNCOMPRESSED,
943                    )
944                    .add(
945                        "s2",
946                        TSDataType::INT32,
947                        TSEncoding::PLAIN,
948                        CompressionType::UNCOMPRESSED,
949                    )
950                    .build(),
951            )
952            .build();
953
954        let epoch_time_ms = SystemTime::now()
955            .duration_since(UNIX_EPOCH)
956            .unwrap()
957            .as_millis();
958
959        let filename = format!("target/{}-1-0-0.tsfile", epoch_time_ms);
960        let mut writer = TsFileWriter::new(filename.as_str(), schema, Default::default()).unwrap();
961
962        for i in 0..100 {
963            writer.write(device, "s1", i, IoTDBValue::INT(i as i32));
964            writer.write(device, "s2", i, IoTDBValue::INT(i as i32));
965        }
966
967        writer.close();
968    }
969
970    #[test]
971    fn write_i64() {
972        let schema = TsFileSchemaBuilder::new()
973            .add(
974                "d1",
975                DeviceBuilder::new()
976                    .add(
977                        "s1",
978                        TSDataType::INT64,
979                        TSEncoding::PLAIN,
980                        CompressionType::UNCOMPRESSED,
981                    )
982                    .build(),
983            )
984            .build();
985
986        let mut writer =
987            TsFileWriter::new("target/write_long.tsfile", schema, Default::default()).unwrap();
988
989        let result = writer.write("d1", "s1", 0, IoTDBValue::LONG(0));
990
991        match result {
992            Ok(_) => {}
993            Err(_) => {
994                assert!(false);
995            }
996        }
997
998        writer.close();
999    }
1000
1001    #[test]
1002    fn write_float() {
1003        let schema = TsFileSchemaBuilder::new()
1004            .add(
1005                "d1",
1006                DeviceBuilder::new()
1007                    .add(
1008                        "s1",
1009                        TSDataType::FLOAT,
1010                        TSEncoding::PLAIN,
1011                        CompressionType::UNCOMPRESSED,
1012                    )
1013                    .build(),
1014            )
1015            .build();
1016
1017        let mut writer =
1018            TsFileWriter::new("target/write_float.tsfile", schema, Default::default()).unwrap();
1019
1020        let result = writer.write("d1", "s1", 0, IoTDBValue::FLOAT(3.141));
1021
1022        match result {
1023            Ok(_) => {}
1024            Err(_) => {
1025                assert!(false);
1026            }
1027        }
1028
1029        writer.close();
1030    }
1031
1032    #[test]
1033    fn read_var_int() {
1034        for number in [
1035            1, 12, 123, 1234, 12345, 123456, 1234567, 12345678, 123456789,
1036        ] {
1037            let mut result: Vec<u8> = vec![];
1038
1039            // Write it
1040            write_var_u32(number, &mut result);
1041            // Read it back
1042            let result: u32 = read_var_u32(&mut result.as_slice()).unwrap();
1043
1044            assert_eq!(number, result);
1045        }
1046    }
1047
1048    #[test]
1049    fn write_var_int() {
1050        let number: u32 = 123456789;
1051        let mut result: Vec<u8> = vec![];
1052        let position = write_var_u32(number, &mut result).unwrap();
1053
1054        assert_eq!(position, 4);
1055        assert_eq!(
1056            result.as_slice(),
1057            [0b10010101, 0b10011010, 0b11101111, 0b00111010]
1058        );
1059    }
1060
1061    #[test]
1062    fn write_var_int_2() {
1063        let number: u32 = 128;
1064        let mut result: Vec<u8> = vec![];
1065        let position = write_var_u32(number, &mut result).unwrap();
1066
1067        assert_eq!(position, 2);
1068        assert_eq!(result.as_slice(), [128, 1]);
1069    }
1070
1071    #[test]
1072    fn write_var_int_3() {
1073        let number: u32 = 13;
1074        let mut result: Vec<u8> = vec![];
1075        let position = write_var_u32(number, &mut result).unwrap();
1076
1077        assert_eq!(position, 1);
1078        assert_eq!(result.as_slice(), [13]);
1079    }
1080
1081    #[test]
1082    fn pre_write_var_int() {
1083        let mut number: u32 = 123456789;
1084        let bytes: [u8; 4] = number.to_be_bytes();
1085        assert_eq!(bytes, [0b00000111, 0b01011011, 0b11001101, 0b00010101]);
1086
1087        let mut buffer: Vec<u8> = vec![];
1088
1089        // Now compress them
1090        let mut position: u8 = 1;
1091
1092        while (number & 0xFFFFFF80) != 0 {
1093            buffer.push(((number & 0x7F) | 0x80) as u8);
1094            number >>= 7;
1095            position += 1;
1096        }
1097
1098        buffer.push((number & 0x7F) as u8);
1099
1100        assert_eq!(buffer, [0b10010101, 0b10011010, 0b11101111, 0b00111010]);
1101        assert_eq!(position, 4);
1102    }
1103
1104    #[test]
1105    fn write_multiple_types() {
1106        let expected = [
1107            0x54, 0x73, 0x46, 0x69, 0x6C, 0x65, 0x03, 0x00, 0x04, 0x64, 0x31, 0x05, 0x04, 0x73,
1108            0x31, 0x1C, 0x01, 0x00, 0x00, 0x1A, 0x1A, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1109            0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
1110            0x00, 0x00, 0x00, 0x01, 0x1A, 0x05, 0x04, 0x73, 0x32, 0x23, 0x02, 0x00, 0x00, 0x21,
1111            0x21, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF,
1112            0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
1113            0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x05, 0x04, 0x73, 0x33, 0x1F, 0x03, 0x00, 0x00,
1114            0x1D, 0x1D, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF,
1115            0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x41,
1116            0x70, 0x00, 0x00, 0x02, 0x00, 0x04, 0x73, 0x31, 0x01, 0x08, 0x01, 0x00, 0x00, 0x00,
1117            0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
1118            0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
1119            0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00,
1120            0x00, 0x00, 0x0B, 0x00, 0x04, 0x73, 0x32, 0x02, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00,
1121            0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
1122            0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E,
1123            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1124            0x00, 0x0E, 0x40, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1125            0x00, 0x00, 0x00, 0x2F, 0x00, 0x04, 0x73, 0x33, 0x03, 0x08, 0x01, 0x00, 0x00, 0x00,
1126            0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x41,
1127            0x70, 0x00, 0x00, 0x41, 0x70, 0x00, 0x00, 0x41, 0x70, 0x00, 0x00, 0x41, 0x70, 0x00,
1128            0x00, 0x40, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1129            0x00, 0x00, 0x5A, 0x01, 0x04, 0x73, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1130            0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x37, 0x03, 0x01, 0x04, 0x64, 0x31,
1131            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1132            0x01, 0x4C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x04, 0x00,
1133            0x00, 0x00, 0x00, 0x00, 0x24, 0x02, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x01, 0x00,
1134            0x21, 0x00, 0x00, 0x18, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00,
1135            0x02, 0x20, 0x80, 0x02, 0x05, 0x00, 0x00, 0x00, 0x41, 0x54, 0x73, 0x46, 0x69, 0x6C,
1136            0x65,
1137        ];
1138
1139        let schema = TsFileSchemaBuilder::new()
1140            .add(
1141                "d1",
1142                DeviceBuilder::new()
1143                    .add(
1144                        "s1",
1145                        TSDataType::INT32,
1146                        TSEncoding::PLAIN,
1147                        CompressionType::UNCOMPRESSED,
1148                    )
1149                    .add(
1150                        "s2",
1151                        TSDataType::INT64,
1152                        TSEncoding::PLAIN,
1153                        CompressionType::UNCOMPRESSED,
1154                    )
1155                    .add(
1156                        "s3",
1157                        TSDataType::FLOAT,
1158                        TSEncoding::PLAIN,
1159                        CompressionType::UNCOMPRESSED,
1160                    )
1161                    .build(),
1162            )
1163            .build();
1164
1165        let buffer: Vec<u8> = vec![];
1166        let buffer_writer = WriteWrapper::new(buffer);
1167
1168        let mut writer =
1169            TsFileWriter::new_from_writer(schema, buffer_writer, Default::default()).unwrap();
1170
1171        writer.write("d1", "s1", 1, IoTDBValue::INT(13));
1172        writer.write("d1", "s2", 1, IoTDBValue::LONG(14));
1173        writer.write("d1", "s3", 1, IoTDBValue::FLOAT(15.0));
1174
1175        writer.close();
1176
1177        // assert_eq!(buffer_writer.writer, expected);
1178        assert_eq!(writer.file_io_writer.out.position, expected.len() as u64);
1179    }
1180
1181    #[test]
1182    fn write_datapoint_int32() {
1183        let expected = [
1184            0x54, 0x73, 0x46, 0x69, 0x6C, 0x65, 0x03, 0x00, 0x04, 0x64, 0x31, 0x05, 0x02, 0x73,
1185            0x1C, 0x01, 0x00, 0x00, 0x1A, 0x1A, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1186            0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
1187            0x00, 0x00, 0x01, 0x1A, 0x02, 0x00, 0x02, 0x73, 0x01, 0x08, 0x01, 0x00, 0x00, 0x00,
1188            0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
1189            0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
1190            0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00,
1191            0x00, 0x00, 0x0B, 0x01, 0x02, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F,
1192            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x03, 0x01, 0x04, 0x64, 0x31, 0x00,
1193            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1194            0x79, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2E, 0x20, 0x00, 0x00, 0x00,
1195            0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1196            0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
1197            0x08, 0x80, 0x02, 0x05, 0x00, 0x00, 0x00, 0x41, 0x54, 0x73, 0x46, 0x69, 0x6C, 0x65,
1198        ];
1199
1200        let schema = TsFileSchemaBuilder::new()
1201            .add(
1202                "d1",
1203                DeviceBuilder::new()
1204                    .add(
1205                        "s",
1206                        TSDataType::INT32,
1207                        TSEncoding::PLAIN,
1208                        CompressionType::UNCOMPRESSED,
1209                    )
1210                    .build(),
1211            )
1212            .build();
1213
1214        let buffer: Vec<u8> = vec![];
1215        let buffer_writer = WriteWrapper::new(buffer);
1216
1217        let mut writer =
1218            TsFileWriter::new_from_writer(schema, buffer_writer, Default::default()).unwrap();
1219
1220        writer.write("d1", "s", 1, IoTDBValue::INT(13));
1221
1222        writer.close();
1223
1224        assert_eq!(writer.file_io_writer.out.writer, expected);
1225    }
1226
1227    #[test]
1228    fn write_datapoint_int64() {
1229        let expected = [
1230            0x54, 0x73, 0x46, 0x69, 0x6C, 0x65, 0x03, 0x00, 0x04, 0x64, 0x31, 0x05, 0x02, 0x73,
1231            0x23, 0x02, 0x00, 0x00, 0x21, 0x21, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1232            0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
1233            0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x02, 0x00, 0x02,
1234            0x73, 0x02, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
1235            0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D,
1236            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1237            0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x40, 0x2A, 0x00, 0x00,
1238            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x01, 0x02,
1239            0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00,
1240            0x00, 0x00, 0x7C, 0x03, 0x01, 0x04, 0x64, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1241            0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00, 0x00,
1242            0x00, 0x00, 0x00, 0x00, 0x35, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
1243            0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
1244            0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80, 0x02, 0x05, 0x00,
1245            0x00, 0x00, 0x41, 0x54, 0x73, 0x46, 0x69, 0x6C, 0x65,
1246        ];
1247
1248        let schema = TsFileSchemaBuilder::new()
1249            .add(
1250                "d1",
1251                DeviceBuilder::new()
1252                    .add(
1253                        "s",
1254                        TSDataType::INT64,
1255                        TSEncoding::PLAIN,
1256                        CompressionType::UNCOMPRESSED,
1257                    )
1258                    .build(),
1259            )
1260            .build();
1261
1262        let buffer: Vec<u8> = vec![];
1263        let buffer_writer = WriteWrapper::new(buffer);
1264
1265        let mut writer =
1266            TsFileWriter::new_from_writer(schema, buffer_writer, Default::default()).unwrap();
1267
1268        writer.write("d1", "s", 1, IoTDBValue::LONG(13));
1269
1270        writer.close();
1271
1272        assert_eq!(writer.file_io_writer.out.writer, expected);
1273    }
1274
1275    #[test]
1276    fn write_datapoint_float() {
1277        let expected = [
1278            0x54, 0x73, 0x46, 0x69, 0x6C, 0x65, 0x03, 0x00, 0x04, 0x64, 0x31, 0x05, 0x02, 0x73,
1279            0x1F, 0x03, 0x00, 0x00, 0x1D, 0x1D, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1280            0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
1281            0x00, 0x00, 0x01, 0x41, 0x50, 0x00, 0x00, 0x02, 0x00, 0x02, 0x73, 0x03, 0x08, 0x01,
1282            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1283            0x00, 0x01, 0x41, 0x50, 0x00, 0x00, 0x41, 0x50, 0x00, 0x00, 0x41, 0x50, 0x00, 0x00,
1284            0x41, 0x50, 0x00, 0x00, 0x40, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1285            0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x01, 0x02, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00,
1286            0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x03, 0x01, 0x04,
1287            0x64, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00,
1288            0x00, 0x00, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x20,
1289            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1290            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
1291            0x00, 0x00, 0x00, 0x08, 0x80, 0x02, 0x05, 0x00, 0x00, 0x00, 0x41, 0x54, 0x73, 0x46,
1292            0x69, 0x6C, 0x65,
1293        ];
1294
1295        let schema = TsFileSchemaBuilder::new()
1296            .add(
1297                "d1",
1298                DeviceBuilder::new()
1299                    .add(
1300                        "s",
1301                        TSDataType::FLOAT,
1302                        TSEncoding::PLAIN,
1303                        CompressionType::UNCOMPRESSED,
1304                    )
1305                    .build(),
1306            )
1307            .build();
1308
1309        let buffer: Vec<u8> = vec![];
1310        let buffer_writer = WriteWrapper::new(buffer);
1311
1312        let mut writer =
1313            TsFileWriter::new_from_writer(schema, buffer_writer, Default::default()).unwrap();
1314
1315        writer.write("d1", "s", 1, IoTDBValue::FLOAT(13.0));
1316
1317        writer.close();
1318
1319        assert_eq!(writer.file_io_writer.out.writer, expected);
1320    }
1321
1322    #[test]
1323    fn write_datapoint_int32_1000() {
1324        let expected = [
1325            0x54, 0x73, 0x46, 0x69, 0x6C, 0x65, 0x03, 0x00, 0x04, 0x64, 0x31, 0x05, 0x02, 0x73,
1326            0xD8, 0x10, 0x01, 0x00, 0x00, 0xD4, 0x10, 0xD4, 0x10, 0xC0, 0x01, 0x00, 0x00, 0x00,
1327            0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
1328            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
1329            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
1330            0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1331            0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00,
1332            0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1333            0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x83, 0x00, 0x00, 0x00, 0x80, 0x00,
1334            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1335            0x00, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
1336            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
1337            0x85, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1338            0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x06, 0x00, 0x00, 0x00,
1339            0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
1340            0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x87, 0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C,
1341            0x0E, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E, 0x20, 0x22, 0x24, 0x26, 0x28,
1342            0x2A, 0x2C, 0x2E, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3A, 0x3C, 0x3E, 0x40, 0x42, 0x44,
1343            0x46, 0x48, 0x4A, 0x4C, 0x4E, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5A, 0x5C, 0x5E, 0x60,
1344            0x62, 0x64, 0x66, 0x68, 0x6A, 0x6C, 0x6E, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7A, 0x7C,
1345            0x7E, 0x80, 0x01, 0x82, 0x01, 0x84, 0x01, 0x86, 0x01, 0x88, 0x01, 0x8A, 0x01, 0x8C,
1346            0x01, 0x8E, 0x01, 0x90, 0x01, 0x92, 0x01, 0x94, 0x01, 0x96, 0x01, 0x98, 0x01, 0x9A,
1347            0x01, 0x9C, 0x01, 0x9E, 0x01, 0xA0, 0x01, 0xA2, 0x01, 0xA4, 0x01, 0xA6, 0x01, 0xA8,
1348            0x01, 0xAA, 0x01, 0xAC, 0x01, 0xAE, 0x01, 0xB0, 0x01, 0xB2, 0x01, 0xB4, 0x01, 0xB6,
1349            0x01, 0xB8, 0x01, 0xBA, 0x01, 0xBC, 0x01, 0xBE, 0x01, 0xC0, 0x01, 0xC2, 0x01, 0xC4,
1350            0x01, 0xC6, 0x01, 0xC8, 0x01, 0xCA, 0x01, 0xCC, 0x01, 0xCE, 0x01, 0xD0, 0x01, 0xD2,
1351            0x01, 0xD4, 0x01, 0xD6, 0x01, 0xD8, 0x01, 0xDA, 0x01, 0xDC, 0x01, 0xDE, 0x01, 0xE0,
1352            0x01, 0xE2, 0x01, 0xE4, 0x01, 0xE6, 0x01, 0xE8, 0x01, 0xEA, 0x01, 0xEC, 0x01, 0xEE,
1353            0x01, 0xF0, 0x01, 0xF2, 0x01, 0xF4, 0x01, 0xF6, 0x01, 0xF8, 0x01, 0xFA, 0x01, 0xFC,
1354            0x01, 0xFE, 0x01, 0x80, 0x02, 0x82, 0x02, 0x84, 0x02, 0x86, 0x02, 0x88, 0x02, 0x8A,
1355            0x02, 0x8C, 0x02, 0x8E, 0x02, 0x90, 0x02, 0x92, 0x02, 0x94, 0x02, 0x96, 0x02, 0x98,
1356            0x02, 0x9A, 0x02, 0x9C, 0x02, 0x9E, 0x02, 0xA0, 0x02, 0xA2, 0x02, 0xA4, 0x02, 0xA6,
1357            0x02, 0xA8, 0x02, 0xAA, 0x02, 0xAC, 0x02, 0xAE, 0x02, 0xB0, 0x02, 0xB2, 0x02, 0xB4,
1358            0x02, 0xB6, 0x02, 0xB8, 0x02, 0xBA, 0x02, 0xBC, 0x02, 0xBE, 0x02, 0xC0, 0x02, 0xC2,
1359            0x02, 0xC4, 0x02, 0xC6, 0x02, 0xC8, 0x02, 0xCA, 0x02, 0xCC, 0x02, 0xCE, 0x02, 0xD0,
1360            0x02, 0xD2, 0x02, 0xD4, 0x02, 0xD6, 0x02, 0xD8, 0x02, 0xDA, 0x02, 0xDC, 0x02, 0xDE,
1361            0x02, 0xE0, 0x02, 0xE2, 0x02, 0xE4, 0x02, 0xE6, 0x02, 0xE8, 0x02, 0xEA, 0x02, 0xEC,
1362            0x02, 0xEE, 0x02, 0xF0, 0x02, 0xF2, 0x02, 0xF4, 0x02, 0xF6, 0x02, 0xF8, 0x02, 0xFA,
1363            0x02, 0xFC, 0x02, 0xFE, 0x02, 0x80, 0x03, 0x82, 0x03, 0x84, 0x03, 0x86, 0x03, 0x88,
1364            0x03, 0x8A, 0x03, 0x8C, 0x03, 0x8E, 0x03, 0x90, 0x03, 0x92, 0x03, 0x94, 0x03, 0x96,
1365            0x03, 0x98, 0x03, 0x9A, 0x03, 0x9C, 0x03, 0x9E, 0x03, 0xA0, 0x03, 0xA2, 0x03, 0xA4,
1366            0x03, 0xA6, 0x03, 0xA8, 0x03, 0xAA, 0x03, 0xAC, 0x03, 0xAE, 0x03, 0xB0, 0x03, 0xB2,
1367            0x03, 0xB4, 0x03, 0xB6, 0x03, 0xB8, 0x03, 0xBA, 0x03, 0xBC, 0x03, 0xBE, 0x03, 0xC0,
1368            0x03, 0xC2, 0x03, 0xC4, 0x03, 0xC6, 0x03, 0xC8, 0x03, 0xCA, 0x03, 0xCC, 0x03, 0xCE,
1369            0x03, 0xD0, 0x03, 0xD2, 0x03, 0xD4, 0x03, 0xD6, 0x03, 0xD8, 0x03, 0xDA, 0x03, 0xDC,
1370            0x03, 0xDE, 0x03, 0xE0, 0x03, 0xE2, 0x03, 0xE4, 0x03, 0xE6, 0x03, 0xE8, 0x03, 0xEA,
1371            0x03, 0xEC, 0x03, 0xEE, 0x03, 0xF0, 0x03, 0xF2, 0x03, 0xF4, 0x03, 0xF6, 0x03, 0xF8,
1372            0x03, 0xFA, 0x03, 0xFC, 0x03, 0xFE, 0x03, 0x80, 0x04, 0x82, 0x04, 0x84, 0x04, 0x86,
1373            0x04, 0x88, 0x04, 0x8A, 0x04, 0x8C, 0x04, 0x8E, 0x04, 0x90, 0x04, 0x92, 0x04, 0x94,
1374            0x04, 0x96, 0x04, 0x98, 0x04, 0x9A, 0x04, 0x9C, 0x04, 0x9E, 0x04, 0xA0, 0x04, 0xA2,
1375            0x04, 0xA4, 0x04, 0xA6, 0x04, 0xA8, 0x04, 0xAA, 0x04, 0xAC, 0x04, 0xAE, 0x04, 0xB0,
1376            0x04, 0xB2, 0x04, 0xB4, 0x04, 0xB6, 0x04, 0xB8, 0x04, 0xBA, 0x04, 0xBC, 0x04, 0xBE,
1377            0x04, 0xC0, 0x04, 0xC2, 0x04, 0xC4, 0x04, 0xC6, 0x04, 0xC8, 0x04, 0xCA, 0x04, 0xCC,
1378            0x04, 0xCE, 0x04, 0xD0, 0x04, 0xD2, 0x04, 0xD4, 0x04, 0xD6, 0x04, 0xD8, 0x04, 0xDA,
1379            0x04, 0xDC, 0x04, 0xDE, 0x04, 0xE0, 0x04, 0xE2, 0x04, 0xE4, 0x04, 0xE6, 0x04, 0xE8,
1380            0x04, 0xEA, 0x04, 0xEC, 0x04, 0xEE, 0x04, 0xF0, 0x04, 0xF2, 0x04, 0xF4, 0x04, 0xF6,
1381            0x04, 0xF8, 0x04, 0xFA, 0x04, 0xFC, 0x04, 0xFE, 0x04, 0x80, 0x05, 0x82, 0x05, 0x84,
1382            0x05, 0x86, 0x05, 0x88, 0x05, 0x8A, 0x05, 0x8C, 0x05, 0x8E, 0x05, 0x90, 0x05, 0x92,
1383            0x05, 0x94, 0x05, 0x96, 0x05, 0x98, 0x05, 0x9A, 0x05, 0x9C, 0x05, 0x9E, 0x05, 0xA0,
1384            0x05, 0xA2, 0x05, 0xA4, 0x05, 0xA6, 0x05, 0xA8, 0x05, 0xAA, 0x05, 0xAC, 0x05, 0xAE,
1385            0x05, 0xB0, 0x05, 0xB2, 0x05, 0xB4, 0x05, 0xB6, 0x05, 0xB8, 0x05, 0xBA, 0x05, 0xBC,
1386            0x05, 0xBE, 0x05, 0xC0, 0x05, 0xC2, 0x05, 0xC4, 0x05, 0xC6, 0x05, 0xC8, 0x05, 0xCA,
1387            0x05, 0xCC, 0x05, 0xCE, 0x05, 0xD0, 0x05, 0xD2, 0x05, 0xD4, 0x05, 0xD6, 0x05, 0xD8,
1388            0x05, 0xDA, 0x05, 0xDC, 0x05, 0xDE, 0x05, 0xE0, 0x05, 0xE2, 0x05, 0xE4, 0x05, 0xE6,
1389            0x05, 0xE8, 0x05, 0xEA, 0x05, 0xEC, 0x05, 0xEE, 0x05, 0xF0, 0x05, 0xF2, 0x05, 0xF4,
1390            0x05, 0xF6, 0x05, 0xF8, 0x05, 0xFA, 0x05, 0xFC, 0x05, 0xFE, 0x05, 0x80, 0x06, 0x82,
1391            0x06, 0x84, 0x06, 0x86, 0x06, 0x88, 0x06, 0x8A, 0x06, 0x8C, 0x06, 0x8E, 0x06, 0x90,
1392            0x06, 0x92, 0x06, 0x94, 0x06, 0x96, 0x06, 0x98, 0x06, 0x9A, 0x06, 0x9C, 0x06, 0x9E,
1393            0x06, 0xA0, 0x06, 0xA2, 0x06, 0xA4, 0x06, 0xA6, 0x06, 0xA8, 0x06, 0xAA, 0x06, 0xAC,
1394            0x06, 0xAE, 0x06, 0xB0, 0x06, 0xB2, 0x06, 0xB4, 0x06, 0xB6, 0x06, 0xB8, 0x06, 0xBA,
1395            0x06, 0xBC, 0x06, 0xBE, 0x06, 0xC0, 0x06, 0xC2, 0x06, 0xC4, 0x06, 0xC6, 0x06, 0xC8,
1396            0x06, 0xCA, 0x06, 0xCC, 0x06, 0xCE, 0x06, 0xD0, 0x06, 0xD2, 0x06, 0xD4, 0x06, 0xD6,
1397            0x06, 0xD8, 0x06, 0xDA, 0x06, 0xDC, 0x06, 0xDE, 0x06, 0xE0, 0x06, 0xE2, 0x06, 0xE4,
1398            0x06, 0xE6, 0x06, 0xE8, 0x06, 0xEA, 0x06, 0xEC, 0x06, 0xEE, 0x06, 0xF0, 0x06, 0xF2,
1399            0x06, 0xF4, 0x06, 0xF6, 0x06, 0xF8, 0x06, 0xFA, 0x06, 0xFC, 0x06, 0xFE, 0x06, 0x80,
1400            0x07, 0x82, 0x07, 0x84, 0x07, 0x86, 0x07, 0x88, 0x07, 0x8A, 0x07, 0x8C, 0x07, 0x8E,
1401            0x07, 0x90, 0x07, 0x92, 0x07, 0x94, 0x07, 0x96, 0x07, 0x98, 0x07, 0x9A, 0x07, 0x9C,
1402            0x07, 0x9E, 0x07, 0xA0, 0x07, 0xA2, 0x07, 0xA4, 0x07, 0xA6, 0x07, 0xA8, 0x07, 0xAA,
1403            0x07, 0xAC, 0x07, 0xAE, 0x07, 0xB0, 0x07, 0xB2, 0x07, 0xB4, 0x07, 0xB6, 0x07, 0xB8,
1404            0x07, 0xBA, 0x07, 0xBC, 0x07, 0xBE, 0x07, 0xC0, 0x07, 0xC2, 0x07, 0xC4, 0x07, 0xC6,
1405            0x07, 0xC8, 0x07, 0xCA, 0x07, 0xCC, 0x07, 0xCE, 0x07, 0xD0, 0x07, 0xD2, 0x07, 0xD4,
1406            0x07, 0xD6, 0x07, 0xD8, 0x07, 0xDA, 0x07, 0xDC, 0x07, 0xDE, 0x07, 0xE0, 0x07, 0xE2,
1407            0x07, 0xE4, 0x07, 0xE6, 0x07, 0xE8, 0x07, 0xEA, 0x07, 0xEC, 0x07, 0xEE, 0x07, 0xF0,
1408            0x07, 0xF2, 0x07, 0xF4, 0x07, 0xF6, 0x07, 0xF8, 0x07, 0xFA, 0x07, 0xFC, 0x07, 0xFE,
1409            0x07, 0x80, 0x08, 0x82, 0x08, 0x84, 0x08, 0x86, 0x08, 0x88, 0x08, 0x8A, 0x08, 0x8C,
1410            0x08, 0x8E, 0x08, 0x90, 0x08, 0x92, 0x08, 0x94, 0x08, 0x96, 0x08, 0x98, 0x08, 0x9A,
1411            0x08, 0x9C, 0x08, 0x9E, 0x08, 0xA0, 0x08, 0xA2, 0x08, 0xA4, 0x08, 0xA6, 0x08, 0xA8,
1412            0x08, 0xAA, 0x08, 0xAC, 0x08, 0xAE, 0x08, 0xB0, 0x08, 0xB2, 0x08, 0xB4, 0x08, 0xB6,
1413            0x08, 0xB8, 0x08, 0xBA, 0x08, 0xBC, 0x08, 0xBE, 0x08, 0xC0, 0x08, 0xC2, 0x08, 0xC4,
1414            0x08, 0xC6, 0x08, 0xC8, 0x08, 0xCA, 0x08, 0xCC, 0x08, 0xCE, 0x08, 0xD0, 0x08, 0xD2,
1415            0x08, 0xD4, 0x08, 0xD6, 0x08, 0xD8, 0x08, 0xDA, 0x08, 0xDC, 0x08, 0xDE, 0x08, 0xE0,
1416            0x08, 0xE2, 0x08, 0xE4, 0x08, 0xE6, 0x08, 0xE8, 0x08, 0xEA, 0x08, 0xEC, 0x08, 0xEE,
1417            0x08, 0xF0, 0x08, 0xF2, 0x08, 0xF4, 0x08, 0xF6, 0x08, 0xF8, 0x08, 0xFA, 0x08, 0xFC,
1418            0x08, 0xFE, 0x08, 0x80, 0x09, 0x82, 0x09, 0x84, 0x09, 0x86, 0x09, 0x88, 0x09, 0x8A,
1419            0x09, 0x8C, 0x09, 0x8E, 0x09, 0x90, 0x09, 0x92, 0x09, 0x94, 0x09, 0x96, 0x09, 0x98,
1420            0x09, 0x9A, 0x09, 0x9C, 0x09, 0x9E, 0x09, 0xA0, 0x09, 0xA2, 0x09, 0xA4, 0x09, 0xA6,
1421            0x09, 0xA8, 0x09, 0xAA, 0x09, 0xAC, 0x09, 0xAE, 0x09, 0xB0, 0x09, 0xB2, 0x09, 0xB4,
1422            0x09, 0xB6, 0x09, 0xB8, 0x09, 0xBA, 0x09, 0xBC, 0x09, 0xBE, 0x09, 0xC0, 0x09, 0xC2,
1423            0x09, 0xC4, 0x09, 0xC6, 0x09, 0xC8, 0x09, 0xCA, 0x09, 0xCC, 0x09, 0xCE, 0x09, 0xD0,
1424            0x09, 0xD2, 0x09, 0xD4, 0x09, 0xD6, 0x09, 0xD8, 0x09, 0xDA, 0x09, 0xDC, 0x09, 0xDE,
1425            0x09, 0xE0, 0x09, 0xE2, 0x09, 0xE4, 0x09, 0xE6, 0x09, 0xE8, 0x09, 0xEA, 0x09, 0xEC,
1426            0x09, 0xEE, 0x09, 0xF0, 0x09, 0xF2, 0x09, 0xF4, 0x09, 0xF6, 0x09, 0xF8, 0x09, 0xFA,
1427            0x09, 0xFC, 0x09, 0xFE, 0x09, 0x80, 0x0A, 0x82, 0x0A, 0x84, 0x0A, 0x86, 0x0A, 0x88,
1428            0x0A, 0x8A, 0x0A, 0x8C, 0x0A, 0x8E, 0x0A, 0x90, 0x0A, 0x92, 0x0A, 0x94, 0x0A, 0x96,
1429            0x0A, 0x98, 0x0A, 0x9A, 0x0A, 0x9C, 0x0A, 0x9E, 0x0A, 0xA0, 0x0A, 0xA2, 0x0A, 0xA4,
1430            0x0A, 0xA6, 0x0A, 0xA8, 0x0A, 0xAA, 0x0A, 0xAC, 0x0A, 0xAE, 0x0A, 0xB0, 0x0A, 0xB2,
1431            0x0A, 0xB4, 0x0A, 0xB6, 0x0A, 0xB8, 0x0A, 0xBA, 0x0A, 0xBC, 0x0A, 0xBE, 0x0A, 0xC0,
1432            0x0A, 0xC2, 0x0A, 0xC4, 0x0A, 0xC6, 0x0A, 0xC8, 0x0A, 0xCA, 0x0A, 0xCC, 0x0A, 0xCE,
1433            0x0A, 0xD0, 0x0A, 0xD2, 0x0A, 0xD4, 0x0A, 0xD6, 0x0A, 0xD8, 0x0A, 0xDA, 0x0A, 0xDC,
1434            0x0A, 0xDE, 0x0A, 0xE0, 0x0A, 0xE2, 0x0A, 0xE4, 0x0A, 0xE6, 0x0A, 0xE8, 0x0A, 0xEA,
1435            0x0A, 0xEC, 0x0A, 0xEE, 0x0A, 0xF0, 0x0A, 0xF2, 0x0A, 0xF4, 0x0A, 0xF6, 0x0A, 0xF8,
1436            0x0A, 0xFA, 0x0A, 0xFC, 0x0A, 0xFE, 0x0A, 0x80, 0x0B, 0x82, 0x0B, 0x84, 0x0B, 0x86,
1437            0x0B, 0x88, 0x0B, 0x8A, 0x0B, 0x8C, 0x0B, 0x8E, 0x0B, 0x90, 0x0B, 0x92, 0x0B, 0x94,
1438            0x0B, 0x96, 0x0B, 0x98, 0x0B, 0x9A, 0x0B, 0x9C, 0x0B, 0x9E, 0x0B, 0xA0, 0x0B, 0xA2,
1439            0x0B, 0xA4, 0x0B, 0xA6, 0x0B, 0xA8, 0x0B, 0xAA, 0x0B, 0xAC, 0x0B, 0xAE, 0x0B, 0xB0,
1440            0x0B, 0xB2, 0x0B, 0xB4, 0x0B, 0xB6, 0x0B, 0xB8, 0x0B, 0xBA, 0x0B, 0xBC, 0x0B, 0xBE,
1441            0x0B, 0xC0, 0x0B, 0xC2, 0x0B, 0xC4, 0x0B, 0xC6, 0x0B, 0xC8, 0x0B, 0xCA, 0x0B, 0xCC,
1442            0x0B, 0xCE, 0x0B, 0xD0, 0x0B, 0xD2, 0x0B, 0xD4, 0x0B, 0xD6, 0x0B, 0xD8, 0x0B, 0xDA,
1443            0x0B, 0xDC, 0x0B, 0xDE, 0x0B, 0xE0, 0x0B, 0xE2, 0x0B, 0xE4, 0x0B, 0xE6, 0x0B, 0xE8,
1444            0x0B, 0xEA, 0x0B, 0xEC, 0x0B, 0xEE, 0x0B, 0xF0, 0x0B, 0xF2, 0x0B, 0xF4, 0x0B, 0xF6,
1445            0x0B, 0xF8, 0x0B, 0xFA, 0x0B, 0xFC, 0x0B, 0xFE, 0x0B, 0x80, 0x0C, 0x82, 0x0C, 0x84,
1446            0x0C, 0x86, 0x0C, 0x88, 0x0C, 0x8A, 0x0C, 0x8C, 0x0C, 0x8E, 0x0C, 0x90, 0x0C, 0x92,
1447            0x0C, 0x94, 0x0C, 0x96, 0x0C, 0x98, 0x0C, 0x9A, 0x0C, 0x9C, 0x0C, 0x9E, 0x0C, 0xA0,
1448            0x0C, 0xA2, 0x0C, 0xA4, 0x0C, 0xA6, 0x0C, 0xA8, 0x0C, 0xAA, 0x0C, 0xAC, 0x0C, 0xAE,
1449            0x0C, 0xB0, 0x0C, 0xB2, 0x0C, 0xB4, 0x0C, 0xB6, 0x0C, 0xB8, 0x0C, 0xBA, 0x0C, 0xBC,
1450            0x0C, 0xBE, 0x0C, 0xC0, 0x0C, 0xC2, 0x0C, 0xC4, 0x0C, 0xC6, 0x0C, 0xC8, 0x0C, 0xCA,
1451            0x0C, 0xCC, 0x0C, 0xCE, 0x0C, 0xD0, 0x0C, 0xD2, 0x0C, 0xD4, 0x0C, 0xD6, 0x0C, 0xD8,
1452            0x0C, 0xDA, 0x0C, 0xDC, 0x0C, 0xDE, 0x0C, 0xE0, 0x0C, 0xE2, 0x0C, 0xE4, 0x0C, 0xE6,
1453            0x0C, 0xE8, 0x0C, 0xEA, 0x0C, 0xEC, 0x0C, 0xEE, 0x0C, 0xF0, 0x0C, 0xF2, 0x0C, 0xF4,
1454            0x0C, 0xF6, 0x0C, 0xF8, 0x0C, 0xFA, 0x0C, 0xFC, 0x0C, 0xFE, 0x0C, 0x80, 0x0D, 0x82,
1455            0x0D, 0x84, 0x0D, 0x86, 0x0D, 0x88, 0x0D, 0x8A, 0x0D, 0x8C, 0x0D, 0x8E, 0x0D, 0x90,
1456            0x0D, 0x92, 0x0D, 0x94, 0x0D, 0x96, 0x0D, 0x98, 0x0D, 0x9A, 0x0D, 0x9C, 0x0D, 0x9E,
1457            0x0D, 0xA0, 0x0D, 0xA2, 0x0D, 0xA4, 0x0D, 0xA6, 0x0D, 0xA8, 0x0D, 0xAA, 0x0D, 0xAC,
1458            0x0D, 0xAE, 0x0D, 0xB0, 0x0D, 0xB2, 0x0D, 0xB4, 0x0D, 0xB6, 0x0D, 0xB8, 0x0D, 0xBA,
1459            0x0D, 0xBC, 0x0D, 0xBE, 0x0D, 0xC0, 0x0D, 0xC2, 0x0D, 0xC4, 0x0D, 0xC6, 0x0D, 0xC8,
1460            0x0D, 0xCA, 0x0D, 0xCC, 0x0D, 0xCE, 0x0D, 0xD0, 0x0D, 0xD2, 0x0D, 0xD4, 0x0D, 0xD6,
1461            0x0D, 0xD8, 0x0D, 0xDA, 0x0D, 0xDC, 0x0D, 0xDE, 0x0D, 0xE0, 0x0D, 0xE2, 0x0D, 0xE4,
1462            0x0D, 0xE6, 0x0D, 0xE8, 0x0D, 0xEA, 0x0D, 0xEC, 0x0D, 0xEE, 0x0D, 0xF0, 0x0D, 0xF2,
1463            0x0D, 0xF4, 0x0D, 0xF6, 0x0D, 0xF8, 0x0D, 0xFA, 0x0D, 0xFC, 0x0D, 0xFE, 0x0D, 0x80,
1464            0x0E, 0x82, 0x0E, 0x84, 0x0E, 0x86, 0x0E, 0x88, 0x0E, 0x8A, 0x0E, 0x8C, 0x0E, 0x8E,
1465            0x0E, 0x90, 0x0E, 0x92, 0x0E, 0x94, 0x0E, 0x96, 0x0E, 0x98, 0x0E, 0x9A, 0x0E, 0x9C,
1466            0x0E, 0x9E, 0x0E, 0xA0, 0x0E, 0xA2, 0x0E, 0xA4, 0x0E, 0xA6, 0x0E, 0xA8, 0x0E, 0xAA,
1467            0x0E, 0xAC, 0x0E, 0xAE, 0x0E, 0xB0, 0x0E, 0xB2, 0x0E, 0xB4, 0x0E, 0xB6, 0x0E, 0xB8,
1468            0x0E, 0xBA, 0x0E, 0xBC, 0x0E, 0xBE, 0x0E, 0xC0, 0x0E, 0xC2, 0x0E, 0xC4, 0x0E, 0xC6,
1469            0x0E, 0xC8, 0x0E, 0xCA, 0x0E, 0xCC, 0x0E, 0xCE, 0x0E, 0xD0, 0x0E, 0xD2, 0x0E, 0xD4,
1470            0x0E, 0xD6, 0x0E, 0xD8, 0x0E, 0xDA, 0x0E, 0xDC, 0x0E, 0xDE, 0x0E, 0xE0, 0x0E, 0xE2,
1471            0x0E, 0xE4, 0x0E, 0xE6, 0x0E, 0xE8, 0x0E, 0xEA, 0x0E, 0xEC, 0x0E, 0xEE, 0x0E, 0xF0,
1472            0x0E, 0xF2, 0x0E, 0xF4, 0x0E, 0xF6, 0x0E, 0xF8, 0x0E, 0xFA, 0x0E, 0xFC, 0x0E, 0xFE,
1473            0x0E, 0x80, 0x0F, 0x82, 0x0F, 0x84, 0x0F, 0x86, 0x0F, 0x88, 0x0F, 0x8A, 0x0F, 0x8C,
1474            0x0F, 0x8E, 0x0F, 0x90, 0x0F, 0x92, 0x0F, 0x94, 0x0F, 0x96, 0x0F, 0x98, 0x0F, 0x9A,
1475            0x0F, 0x9C, 0x0F, 0x9E, 0x0F, 0xA0, 0x0F, 0xA2, 0x0F, 0xA4, 0x0F, 0xA6, 0x0F, 0xA8,
1476            0x0F, 0xAA, 0x0F, 0xAC, 0x0F, 0xAE, 0x0F, 0xB0, 0x0F, 0xB2, 0x0F, 0xB4, 0x0F, 0xB6,
1477            0x0F, 0xB8, 0x0F, 0xBA, 0x0F, 0xBC, 0x0F, 0xBE, 0x0F, 0xC0, 0x0F, 0xC2, 0x0F, 0xC4,
1478            0x0F, 0xC6, 0x0F, 0xC8, 0x0F, 0xCA, 0x0F, 0xCC, 0x0F, 0xCE, 0x0F, 0xD0, 0x0F, 0x02,
1479            0x00, 0x02, 0x73, 0x01, 0x08, 0xE9, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1480            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x00,
1481            0x00, 0x03, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xE8, 0x00, 0x00, 0x00,
1482            0x00, 0x00, 0x07, 0xA3, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x01,
1483            0x02, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x6C, 0x00, 0x00, 0x00, 0x00,
1484            0x00, 0x00, 0x08, 0xA3, 0x03, 0x01, 0x04, 0x64, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00,
1485            0x00, 0x08, 0xA3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xB7, 0x01, 0x00, 0x00,
1486            0x00, 0x00, 0x00, 0x00, 0x08, 0x6B, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1487            0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
1488            0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80, 0x02, 0x05,
1489            0x00, 0x00, 0x00, 0x41, 0x54, 0x73, 0x46, 0x69, 0x6C, 0x65,
1490        ];
1491
1492        let schema = TsFileSchemaBuilder::new()
1493            .add(
1494                "d1",
1495                DeviceBuilder::new()
1496                    .add(
1497                        "s",
1498                        TSDataType::INT32,
1499                        TSEncoding::PLAIN,
1500                        CompressionType::UNCOMPRESSED,
1501                    )
1502                    .build(),
1503            )
1504            .build();
1505
1506        let buffer: Vec<u8> = vec![];
1507        let buffer_writer = WriteWrapper::new(buffer);
1508
1509        let mut writer =
1510            TsFileWriter::new_from_writer(schema, buffer_writer, Default::default()).unwrap();
1511
1512        for i in 0..1001 {
1513            writer.write("d1", "s", i, IoTDBValue::INT(i as i32));
1514        }
1515
1516        writer.close();
1517
1518        assert_eq!(writer.file_io_writer.out.writer, expected);
1519    }
1520
1521    #[test]
1522    fn write_datapoint_int64_10000() {
1523        let schema = TsFileSchemaBuilder::new()
1524            .add(
1525                "d1",
1526                DeviceBuilder::new()
1527                    .add(
1528                        "s",
1529                        TSDataType::INT64,
1530                        TSEncoding::PLAIN,
1531                        CompressionType::UNCOMPRESSED,
1532                    )
1533                    .build(),
1534            )
1535            .build();
1536
1537        let mut writer =
1538            TsFileWriter::new("target/10000_int64.tsfile", schema, Default::default()).unwrap();
1539
1540        for i in 0..10001 {
1541            writer.write("d1", "s", i, IoTDBValue::LONG(2 * i));
1542        }
1543
1544        writer.close();
1545    }
1546
1547    #[test]
1548    fn write_out_of_order_data() -> Result<(), TsFileError> {
1549        let schema = Schema::simple(
1550            "d1",
1551            "s1",
1552            TSDataType::INT64,
1553            TSEncoding::PLAIN,
1554            CompressionType::UNCOMPRESSED,
1555        );
1556
1557        let mut writer = TsFileWriter::new("target/test.tsfile", schema, Default::default())?;
1558
1559        writer.write("d1", "s1", 1, IoTDBValue::LONG(1))?;
1560        let result = writer.write("d1", "s1", 1, IoTDBValue::LONG(1));
1561
1562        assert_eq!(Some(TsFileError::OutOfOrderData), result.err());
1563
1564        Ok(())
1565    }
1566
1567    #[test]
1568    fn write_i64_snappy() {
1569        let expected = [
1570            0x54, 0x73, 0x46, 0x69, 0x6C, 0x65, 0x03, 0x00, 0x04, 0x64, 0x31, 0x05, 0x04, 0x73,
1571            0x31, 0x19, 0x02, 0x01, 0x00, 0x21, 0x17, 0x21, 0x04, 0x18, 0x00, 0x0D, 0x01, 0x04,
1572            0x7F, 0xFF, 0x09, 0x01, 0x0D, 0x0F, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1573            0x00, 0x0D, 0x02, 0x00, 0x04, 0x73, 0x31, 0x02, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00,
1574            0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
1575            0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D,
1576            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1577            0x00, 0x0D, 0x40, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1578            0x00, 0x00, 0x00, 0x0B, 0x01, 0x04, 0x73, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1579            0x00, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x03, 0x01, 0x04, 0x64,
1580            0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00,
1581            0x00, 0x00, 0x89, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x1F, 0x04,
1582            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1583            0x00, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1584            0x00, 0x02, 0x80, 0x02, 0x05, 0x00, 0x00, 0x00, 0x40, 0x54, 0x73, 0x46, 0x69, 0x6C,
1585            0x65,
1586        ];
1587        let schema = TsFileSchemaBuilder::new()
1588            .add(
1589                "d1",
1590                DeviceBuilder::new()
1591                    .add(
1592                        "s1",
1593                        TSDataType::INT64,
1594                        TSEncoding::PLAIN,
1595                        CompressionType::SNAPPY,
1596                    )
1597                    .build(),
1598            )
1599            .build();
1600
1601        let buffer: Vec<u8> = Vec::new();
1602
1603        let mut writer = TsFileWriter::new_from_writer(schema, buffer, Default::default()).unwrap();
1604
1605        writer.write("d1", "s1", 1, IoTDBValue::LONG(13));
1606        writer.close();
1607
1608        assert_eq!(expected, writer.file_io_writer.out.as_slice());
1609    }
1610
1611    #[test]
1612    fn write_i64_ts2diff() -> Result<(), TsFileError> {
1613        let expected = [
1614            0x54, 0x73, 0x46, 0x69, 0x6C, 0x65, 0x03, 0x00, 0x04, 0x64, 0x31, 0x05, 0x04, 0x73,
1615            0x31, 0x33, 0x02, 0x00, 0x04, 0x31, 0x31, 0x18, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00,
1616            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
1617            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1618            0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1619            0x02, 0x00, 0x04, 0x73, 0x31, 0x02, 0x08, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1620            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00,
1621            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00,
1622            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09,
1623            0x40, 0x46, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1624            0x00, 0x0B, 0x01, 0x04, 0x73, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
1625            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8E, 0x03, 0x01, 0x04, 0x64, 0x31, 0x00,
1626            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1627            0xA3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1F, 0x04, 0x00, 0x00,
1628            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01,
1629            0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
1630            0x80, 0x02, 0x05, 0x00, 0x00, 0x00, 0x40, 0x54, 0x73, 0x46, 0x69, 0x6C, 0x65,
1631        ];
1632        let schema = TsFileSchemaBuilder::new()
1633            .add(
1634                "d1",
1635                DeviceBuilder::new()
1636                    .add(
1637                        "s1",
1638                        TSDataType::INT64,
1639                        TSEncoding::TS2DIFF,
1640                        CompressionType::UNCOMPRESSED,
1641                    )
1642                    .build(),
1643            )
1644            .build();
1645
1646        let buffer: Vec<u8> = Vec::new();
1647
1648        let mut writer = TsFileWriter::new_from_writer(schema, buffer, Default::default()).unwrap();
1649
1650        for i in 0..10 {
1651            writer.write("d1", "s1", i, IoTDBValue::LONG(i))?;
1652        }
1653        writer.close();
1654
1655        assert_eq!(expected, writer.file_io_writer.out.as_slice());
1656
1657        Ok(())
1658    }
1659
1660    #[test]
1661    fn write_i32_ts2diff() -> Result<(), TsFileError> {
1662        let expected = [
1663            0x54, 0x73, 0x46, 0x69, 0x6C, 0x65, 0x03, 0x00, 0x04, 0x64, 0x31, 0x05, 0x04, 0x73,
1664            0x31, 0x2B, 0x01, 0x00, 0x04, 0x29, 0x29, 0x18, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00,
1665            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
1666            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1667            0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x73, 0x31, 0x01, 0x08, 0x0A,
1668            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1669            0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00,
1670            0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00,
1671            0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x01, 0x04, 0x73, 0x31, 0x00, 0x00, 0x00, 0x00,
1672            0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x03, 0x01,
1673            0x04, 0x64, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00,
1674            0x00, 0x00, 0x00, 0x00, 0x8B, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E,
1675            0x1F, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1676            0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1677            0x00, 0x00, 0x00, 0x02, 0x80, 0x02, 0x05, 0x00, 0x00, 0x00, 0x40, 0x54, 0x73, 0x46,
1678            0x69, 0x6C, 0x65,
1679        ];
1680        let schema = TsFileSchemaBuilder::new()
1681            .add(
1682                "d1",
1683                DeviceBuilder::new()
1684                    .add(
1685                        "s1",
1686                        TSDataType::INT32,
1687                        TSEncoding::TS2DIFF,
1688                        CompressionType::UNCOMPRESSED,
1689                    )
1690                    .build(),
1691            )
1692            .build();
1693
1694        let buffer: Vec<u8> = Vec::new();
1695
1696        let mut writer = TsFileWriter::new_from_writer(schema, buffer, Default::default()).unwrap();
1697
1698        for i in 0..10 {
1699            writer.write("d1", "s1", i, IoTDBValue::INT(i as i32))?;
1700        }
1701        writer.close();
1702
1703        assert_eq!(expected, writer.file_io_writer.out.as_slice());
1704
1705        Ok(())
1706    }
1707
1708    #[test]
1709    #[ignore = "Is luck dependent due to HashMap"]
1710    fn write_snappy_complex() {
1711        let expected = [
1712            0x54, 0x73, 0x46, 0x69, 0x6C, 0x65, 0x03, 0x00, 0x04, 0x64, 0x31, 0x05, 0x04, 0x73,
1713            0x31, 0x19, 0x02, 0x01, 0x00, 0x21, 0x17, 0x21, 0x04, 0x18, 0x00, 0x0D, 0x01, 0x04,
1714            0x7F, 0xFF, 0x09, 0x01, 0x0D, 0x0F, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1715            0x00, 0x0D, 0x05, 0x04, 0x73, 0x32, 0x1A, 0x03, 0x01, 0x00, 0x1D, 0x18, 0x1D, 0x04,
1716            0x18, 0x00, 0x0D, 0x01, 0x04, 0x7F, 0xFF, 0x09, 0x01, 0x2C, 0x00, 0x00, 0x00, 0x00,
1717            0x00, 0x00, 0x00, 0x01, 0x41, 0x60, 0x00, 0x00, 0x00, 0x04, 0x64, 0x32, 0x05, 0x04,
1718            0x73, 0x31, 0x1A, 0x01, 0x01, 0x00, 0x1A, 0x18, 0x1A, 0x04, 0x18, 0x00, 0x0D, 0x01,
1719            0x40, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
1720            0x00, 0x00, 0x01, 0x1E, 0x02, 0x00, 0x04, 0x73, 0x31, 0x02, 0x08, 0x01, 0x00, 0x00,
1721            0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1722            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1723            0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00,
1724            0x00, 0x00, 0x00, 0x0D, 0x40, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1725            0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x04, 0x73, 0x32, 0x03, 0x08, 0x01, 0x00,
1726            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1727            0x01, 0x41, 0x60, 0x00, 0x00, 0x41, 0x60, 0x00, 0x00, 0x41, 0x60, 0x00, 0x00, 0x41,
1728            0x60, 0x00, 0x00, 0x40, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1729            0x00, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x04, 0x73, 0x31, 0x01, 0x08, 0x01, 0x00, 0x00,
1730            0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1731            0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00,
1732            0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00,
1733            0x00, 0x00, 0x00, 0x52, 0x01, 0x04, 0x73, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1734            0x00, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF3, 0x03, 0x01, 0x04, 0x73,
1735            0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF3, 0x00, 0x00, 0x00, 0x00, 0x00,
1736            0x00, 0x01, 0x2A, 0x03, 0x02, 0x04, 0x64, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1737            0x01, 0x2A, 0x04, 0x64, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3F, 0x00,
1738            0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x54, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1739            0x00, 0x74, 0x20, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x80,
1740            0x00, 0x00, 0x08, 0x01, 0x00, 0x21, 0x40, 0x00, 0x08, 0x80, 0x00, 0x00, 0x00, 0x00,
1741            0x00, 0x02, 0x04, 0x00, 0x00, 0x02, 0x20, 0x80, 0x02, 0x05, 0x00, 0x00, 0x00, 0x4C,
1742            0x54, 0x73, 0x46, 0x69, 0x6C, 0x65,
1743        ];
1744        let schema = TsFileSchemaBuilder::new()
1745            .add(
1746                "d1",
1747                DeviceBuilder::new()
1748                    .add(
1749                        "s1",
1750                        TSDataType::INT64,
1751                        TSEncoding::PLAIN,
1752                        CompressionType::SNAPPY,
1753                    )
1754                    .add(
1755                        "s2",
1756                        TSDataType::FLOAT,
1757                        TSEncoding::PLAIN,
1758                        CompressionType::SNAPPY,
1759                    )
1760                    .build(),
1761            )
1762            .add(
1763                "d2",
1764                DeviceBuilder::new()
1765                    .add(
1766                        "s1",
1767                        TSDataType::INT32,
1768                        TSEncoding::PLAIN,
1769                        CompressionType::SNAPPY,
1770                    )
1771                    .build(),
1772            )
1773            .build();
1774
1775        let buffer: Vec<u8> = Vec::new();
1776
1777        let mut writer = TsFileWriter::new_from_writer(schema, buffer, Default::default()).unwrap();
1778
1779        writer.write("d1", "s1", 1, IoTDBValue::LONG(13));
1780        writer.write("d1", "s2", 1, IoTDBValue::FLOAT(14.0));
1781        writer.write("d2", "s1", 1, IoTDBValue::INT(15));
1782        writer.close();
1783
1784        assert_eq!(expected, writer.file_io_writer.out.as_slice());
1785    }
1786
1787    #[test]
1788    fn use_ts2diff() -> Result<(), TsFileError> {
1789        let schema = Schema::simple(
1790            "d1",
1791            "s1",
1792            TSDataType::INT64,
1793            TSEncoding::TS2DIFF,
1794            CompressionType::UNCOMPRESSED,
1795        );
1796
1797        let mut writer = TsFileWriter::new("target/test.tsfile", schema, Default::default())?;
1798
1799        writer.write("d1", "s1", 1, IoTDBValue::LONG(1))?;
1800
1801        writer.close();
1802
1803        Ok(())
1804    }
1805}
1806
1807pub const ONLY_ONE_PAGE_CHUNK_HEADER: u8 = 5;
1808pub const CHUNK_HEADER: u8 = 1;