• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

apache / iotdb / #10011

06 Sep 2023 11:55AM UTC coverage: 47.651% (-0.003%) from 47.654%
#10011

Pull #11068

travis_ci

web-flow
Merge 42d83cb9e into 720ad0d5b
Pull Request #11068: try opt

97 of 97 new or added lines in 3 files covered. (100.0%)

80187 of 168279 relevant lines covered (47.65%)

0.48 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

62.86
/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/reader/page/ValuePageReader.java
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one
3
 * or more contributor license agreements.  See the NOTICE file
4
 * distributed with this work for additional information
5
 * regarding copyright ownership.  The ASF licenses this file
6
 * to you under the Apache License, Version 2.0 (the
7
 * "License"); you may not use this file except in compliance
8
 * with the License.  You may obtain a copy of the License at
9
 *
10
 *     http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing,
13
 * software distributed under the License is distributed on an
14
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
 * KIND, either express or implied.  See the License for the
16
 * specific language governing permissions and limitations
17
 * under the License.
18
 */
19

20
package org.apache.iotdb.tsfile.read.reader.page;
21

22
import org.apache.iotdb.tsfile.encoding.decoder.Decoder;
23
import org.apache.iotdb.tsfile.exception.write.UnSupportedDataTypeException;
24
import org.apache.iotdb.tsfile.file.header.PageHeader;
25
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
26
import org.apache.iotdb.tsfile.file.metadata.statistics.Statistics;
27
import org.apache.iotdb.tsfile.read.common.BatchData;
28
import org.apache.iotdb.tsfile.read.common.BatchDataFactory;
29
import org.apache.iotdb.tsfile.read.common.TimeRange;
30
import org.apache.iotdb.tsfile.read.common.block.column.ColumnBuilder;
31
import org.apache.iotdb.tsfile.read.filter.basic.Filter;
32
import org.apache.iotdb.tsfile.utils.Binary;
33
import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
34
import org.apache.iotdb.tsfile.utils.TsPrimitiveType;
35

36
import java.nio.ByteBuffer;
37
import java.util.Arrays;
38
import java.util.List;
39

40
public class ValuePageReader {
41

42
  private static final int MASK = 0x80;
43

44
  private final PageHeader pageHeader;
45

46
  private final TSDataType dataType;
47

48
  /** decoder for value column */
49
  private final Decoder valueDecoder;
50

51
  private byte[] bitmap;
52

53
  private int size;
54

55
  /** value column in memory */
56
  protected ByteBuffer valueBuffer;
57

58
  /** A list of deleted intervals. */
59
  private List<TimeRange> deleteIntervalList;
60

61
  private int deleteCursor = 0;
1✔
62

63
  public ValuePageReader(
64
      PageHeader pageHeader, ByteBuffer pageData, TSDataType dataType, Decoder valueDecoder) {
1✔
65
    this.dataType = dataType;
1✔
66
    this.valueDecoder = valueDecoder;
1✔
67
    this.pageHeader = pageHeader;
1✔
68
    if (pageData != null) {
1✔
69
      splitDataToBitmapAndValue(pageData);
1✔
70
    }
71
    this.valueBuffer = pageData;
1✔
72
  }
1✔
73

74
  private void splitDataToBitmapAndValue(ByteBuffer pageData) {
75
    if (!pageData.hasRemaining()) { // Empty Page
1✔
76
      return;
×
77
    }
78
    this.size = ReadWriteIOUtils.readInt(pageData);
1✔
79
    this.bitmap = new byte[(size + 7) / 8];
1✔
80
    pageData.get(bitmap);
1✔
81
    this.valueBuffer = pageData.slice();
1✔
82
  }
1✔
83

84
  /**
85
   * return a BatchData with the corresponding timeBatch, the BatchData's dataType is same as this
86
   * sub sensor
87
   */
88
  public BatchData nextBatch(long[] timeBatch, boolean ascending, Filter filter) {
89
    BatchData pageData = BatchDataFactory.createBatchData(dataType, ascending, false);
×
90
    for (int i = 0; i < timeBatch.length; i++) {
×
91
      if (((bitmap[i / 8] & 0xFF) & (MASK >>> (i % 8))) == 0) {
×
92
        continue;
×
93
      }
94
      long timestamp = timeBatch[i];
×
95
      switch (dataType) {
×
96
        case BOOLEAN:
97
          boolean aBoolean = valueDecoder.readBoolean(valueBuffer);
×
98
          if (!isDeleted(timestamp) && (filter == null || filter.satisfy(timestamp, aBoolean))) {
×
99
            pageData.putBoolean(timestamp, aBoolean);
×
100
          }
101
          break;
102
        case INT32:
103
          int anInt = valueDecoder.readInt(valueBuffer);
×
104
          if (!isDeleted(timestamp) && (filter == null || filter.satisfy(timestamp, anInt))) {
×
105
            pageData.putInt(timestamp, anInt);
×
106
          }
107
          break;
108
        case INT64:
109
          long aLong = valueDecoder.readLong(valueBuffer);
×
110
          if (!isDeleted(timestamp) && (filter == null || filter.satisfy(timestamp, aLong))) {
×
111
            pageData.putLong(timestamp, aLong);
×
112
          }
113
          break;
114
        case FLOAT:
115
          float aFloat = valueDecoder.readFloat(valueBuffer);
×
116
          if (!isDeleted(timestamp) && (filter == null || filter.satisfy(timestamp, aFloat))) {
×
117
            pageData.putFloat(timestamp, aFloat);
×
118
          }
119
          break;
120
        case DOUBLE:
121
          double aDouble = valueDecoder.readDouble(valueBuffer);
×
122
          if (!isDeleted(timestamp) && (filter == null || filter.satisfy(timestamp, aDouble))) {
×
123
            pageData.putDouble(timestamp, aDouble);
×
124
          }
125
          break;
126
        case TEXT:
127
          Binary aBinary = valueDecoder.readBinary(valueBuffer);
×
128
          if (!isDeleted(timestamp) && (filter == null || filter.satisfy(timestamp, aBinary))) {
×
129
            pageData.putBinary(timestamp, aBinary);
×
130
          }
131
          break;
132
        default:
133
          throw new UnSupportedDataTypeException(String.valueOf(dataType));
×
134
      }
135
    }
136
    return pageData.flip();
×
137
  }
138

139
  public TsPrimitiveType nextValue(long timestamp, int timeIndex) {
140
    TsPrimitiveType resultValue = null;
1✔
141
    if (valueBuffer == null || ((bitmap[timeIndex / 8] & 0xFF) & (MASK >>> (timeIndex % 8))) == 0) {
1✔
142
      return null;
1✔
143
    }
144
    switch (dataType) {
1✔
145
      case BOOLEAN:
146
        boolean aBoolean = valueDecoder.readBoolean(valueBuffer);
1✔
147
        if (!isDeleted(timestamp)) {
1✔
148
          resultValue = new TsPrimitiveType.TsBoolean(aBoolean);
1✔
149
        }
150
        break;
151
      case INT32:
152
        int anInt = valueDecoder.readInt(valueBuffer);
1✔
153
        if (!isDeleted(timestamp)) {
1✔
154
          resultValue = new TsPrimitiveType.TsInt(anInt);
1✔
155
        }
156
        break;
157
      case INT64:
158
        long aLong = valueDecoder.readLong(valueBuffer);
1✔
159
        if (!isDeleted(timestamp)) {
1✔
160
          resultValue = new TsPrimitiveType.TsLong(aLong);
1✔
161
        }
162
        break;
163
      case FLOAT:
164
        float aFloat = valueDecoder.readFloat(valueBuffer);
1✔
165
        if (!isDeleted(timestamp)) {
1✔
166
          resultValue = new TsPrimitiveType.TsFloat(aFloat);
1✔
167
        }
168
        break;
169
      case DOUBLE:
170
        double aDouble = valueDecoder.readDouble(valueBuffer);
1✔
171
        if (!isDeleted(timestamp)) {
1✔
172
          resultValue = new TsPrimitiveType.TsDouble(aDouble);
1✔
173
        }
174
        break;
175
      case TEXT:
176
        Binary aBinary = valueDecoder.readBinary(valueBuffer);
1✔
177
        if (!isDeleted(timestamp)) {
1✔
178
          resultValue = new TsPrimitiveType.TsBinary(aBinary);
1✔
179
        }
180
        break;
181
      default:
182
        throw new UnSupportedDataTypeException(String.valueOf(dataType));
×
183
    }
184

185
    return resultValue;
1✔
186
  }
187

188
  /**
189
   * return the value array of the corresponding time, if this sub sensor don't have a value in a
190
   * time, just fill it with null
191
   */
192
  public TsPrimitiveType[] nextValueBatch(long[] timeBatch) {
193
    TsPrimitiveType[] valueBatch = new TsPrimitiveType[size];
1✔
194
    if (valueBuffer == null) {
1✔
195
      return valueBatch;
×
196
    }
197
    for (int i = 0; i < size; i++) {
1✔
198
      if (((bitmap[i / 8] & 0xFF) & (MASK >>> (i % 8))) == 0) {
1✔
199
        continue;
×
200
      }
201
      switch (dataType) {
1✔
202
        case BOOLEAN:
203
          boolean aBoolean = valueDecoder.readBoolean(valueBuffer);
1✔
204
          if (!isDeleted(timeBatch[i])) {
1✔
205
            valueBatch[i] = new TsPrimitiveType.TsBoolean(aBoolean);
1✔
206
          }
207
          break;
208
        case INT32:
209
          int anInt = valueDecoder.readInt(valueBuffer);
1✔
210
          if (!isDeleted(timeBatch[i])) {
1✔
211
            valueBatch[i] = new TsPrimitiveType.TsInt(anInt);
1✔
212
          }
213
          break;
214
        case INT64:
215
          long aLong = valueDecoder.readLong(valueBuffer);
1✔
216
          if (!isDeleted(timeBatch[i])) {
1✔
217
            valueBatch[i] = new TsPrimitiveType.TsLong(aLong);
1✔
218
          }
219
          break;
220
        case FLOAT:
221
          float aFloat = valueDecoder.readFloat(valueBuffer);
1✔
222
          if (!isDeleted(timeBatch[i])) {
1✔
223
            valueBatch[i] = new TsPrimitiveType.TsFloat(aFloat);
1✔
224
          }
225
          break;
226
        case DOUBLE:
227
          double aDouble = valueDecoder.readDouble(valueBuffer);
1✔
228
          if (!isDeleted(timeBatch[i])) {
1✔
229
            valueBatch[i] = new TsPrimitiveType.TsDouble(aDouble);
1✔
230
          }
231
          break;
232
        case TEXT:
233
          Binary aBinary = valueDecoder.readBinary(valueBuffer);
1✔
234
          if (!isDeleted(timeBatch[i])) {
1✔
235
            valueBatch[i] = new TsPrimitiveType.TsBinary(aBinary);
1✔
236
          }
237
          break;
238
        default:
239
          throw new UnSupportedDataTypeException(String.valueOf(dataType));
×
240
      }
241
    }
242
    return valueBatch;
1✔
243
  }
244

245
  public void writeColumnBuilderWithNextBatch(
246
      int readEndIndex,
247
      ColumnBuilder columnBuilder,
248
      boolean[] keepCurrentRow,
249
      boolean[] isDeleted) {
250
    if (valueBuffer == null) {
1✔
251
      for (int i = 0; i < readEndIndex; i++) {
×
252
        if (keepCurrentRow[i]) {
×
253
          columnBuilder.appendNull();
×
254
        }
255
      }
256
      return;
×
257
    }
258
    for (int i = 0; i < readEndIndex; i++) {
1✔
259
      if (((bitmap[i / 8] & 0xFF) & (MASK >>> (i % 8))) == 0) {
1✔
260
        if (keepCurrentRow[i]) {
1✔
261
          columnBuilder.appendNull();
1✔
262
        }
263
        continue;
264
      }
265
      switch (dataType) {
1✔
266
        case BOOLEAN:
267
          boolean aBoolean = valueDecoder.readBoolean(valueBuffer);
1✔
268
          if (keepCurrentRow[i]) {
1✔
269
            if (isDeleted[i]) {
1✔
270
              columnBuilder.appendNull();
×
271
            } else {
272
              columnBuilder.writeBoolean(aBoolean);
1✔
273
            }
274
          }
275
          break;
276
        case INT32:
277
          int anInt = valueDecoder.readInt(valueBuffer);
1✔
278
          if (keepCurrentRow[i]) {
1✔
279
            if (isDeleted[i]) {
1✔
280
              columnBuilder.appendNull();
×
281
            } else {
282
              columnBuilder.writeInt(anInt);
1✔
283
            }
284
          }
285
          break;
286
        case INT64:
287
          long aLong = valueDecoder.readLong(valueBuffer);
1✔
288
          if (keepCurrentRow[i]) {
1✔
289
            if (isDeleted[i]) {
1✔
290
              columnBuilder.appendNull();
1✔
291
            } else {
292
              columnBuilder.writeLong(aLong);
1✔
293
            }
294
          }
295
          break;
296
        case FLOAT:
297
          float aFloat = valueDecoder.readFloat(valueBuffer);
1✔
298
          if (keepCurrentRow[i]) {
1✔
299
            if (isDeleted[i]) {
1✔
300
              columnBuilder.appendNull();
×
301
            } else {
302
              columnBuilder.writeFloat(aFloat);
1✔
303
            }
304
          }
305
          break;
306
        case DOUBLE:
307
          double aDouble = valueDecoder.readDouble(valueBuffer);
1✔
308
          if (keepCurrentRow[i]) {
1✔
309
            if (isDeleted[i]) {
1✔
310
              columnBuilder.appendNull();
1✔
311
            } else {
312
              columnBuilder.writeDouble(aDouble);
1✔
313
            }
314
          }
315
          break;
316
        case TEXT:
317
          Binary aBinary = valueDecoder.readBinary(valueBuffer);
1✔
318
          if (keepCurrentRow[i]) {
1✔
319
            if (isDeleted[i]) {
1✔
320
              columnBuilder.appendNull();
×
321
            } else {
322
              columnBuilder.writeBinary(aBinary);
1✔
323
            }
324
          }
325
          break;
326
        default:
327
          throw new UnSupportedDataTypeException(String.valueOf(dataType));
×
328
      }
329
    }
330
  }
1✔
331

332
  public void writeColumnBuilderWithNextBatch(
333
      int readStartIndex, int readEndIndex, ColumnBuilder columnBuilder) {
334
    if (valueBuffer == null) {
×
335
      for (int i = readStartIndex; i < readEndIndex; i++) {
×
336
        columnBuilder.appendNull();
×
337
      }
338
      return;
×
339
    }
340
    for (int i = readStartIndex; i < readEndIndex; i++) {
×
341
      if (((bitmap[i / 8] & 0xFF) & (MASK >>> (i % 8))) == 0) {
×
342
        columnBuilder.appendNull();
×
343
        continue;
×
344
      }
345
      switch (dataType) {
×
346
        case BOOLEAN:
347
          columnBuilder.writeBoolean(valueDecoder.readBoolean(valueBuffer));
×
348
          break;
×
349
        case INT32:
350
          columnBuilder.writeInt(valueDecoder.readInt(valueBuffer));
×
351
          break;
×
352
        case INT64:
353
          columnBuilder.writeLong(valueDecoder.readLong(valueBuffer));
×
354
          break;
×
355
        case FLOAT:
356
          columnBuilder.writeFloat(valueDecoder.readFloat(valueBuffer));
×
357
          break;
×
358
        case DOUBLE:
359
          columnBuilder.writeDouble(valueDecoder.readDouble(valueBuffer));
×
360
          break;
×
361
        case TEXT:
362
          columnBuilder.writeBinary(valueDecoder.readBinary(valueBuffer));
×
363
          break;
×
364
        default:
365
          throw new UnSupportedDataTypeException(String.valueOf(dataType));
×
366
      }
367
    }
368
  }
×
369

370
  public Statistics getStatistics() {
371
    return pageHeader.getStatistics();
1✔
372
  }
373

374
  public void setDeleteIntervalList(List<TimeRange> list) {
375
    this.deleteIntervalList = list;
1✔
376
  }
1✔
377

378
  public List<TimeRange> getDeleteIntervalList() {
379
    return deleteIntervalList;
×
380
  }
381

382
  public boolean isModified() {
383
    return pageHeader.isModified();
1✔
384
  }
385

386
  protected boolean isDeleted(long timestamp) {
387
    while (deleteIntervalList != null && deleteCursor < deleteIntervalList.size()) {
1✔
388
      if (deleteIntervalList.get(deleteCursor).contains(timestamp)) {
1✔
389
        return true;
1✔
390
      } else if (deleteIntervalList.get(deleteCursor).getMax() < timestamp) {
1✔
391
        deleteCursor++;
1✔
392
      } else {
393
        return false;
1✔
394
      }
395
    }
396
    return false;
1✔
397
  }
398

399
  public void fillIsDeleted(long[] timestamp, boolean[] isDeleted) {
400
    for (int i = 0, n = timestamp.length; i < n; i++) {
1✔
401
      isDeleted[i] = isDeleted(timestamp[i]);
1✔
402
    }
403
  }
1✔
404

405
  public TSDataType getDataType() {
406
    return dataType;
×
407
  }
408

409
  public byte[] getBitmap() {
410
    return Arrays.copyOf(bitmap, bitmap.length);
1✔
411
  }
412
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc