Skip to content

Commit

Permalink
Extract decodeTimestamp method
Browse files Browse the repository at this point in the history
  • Loading branch information
bhhari authored and mbasmanova committed Aug 14, 2019
1 parent b6e9ee9 commit 36bc5fb
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 34 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.facebook.presto.orc.reader;

final class ApacheHiveTimestampDecoder
{
private ApacheHiveTimestampDecoder() {}

// This comes from the Apache Hive ORC code
public static long decodeTimestamp(long seconds, long serializedNanos, long baseTimestampInSeconds)
{
long millis = (seconds + baseTimestampInSeconds) * 1000;
long nanos = parseNanos(serializedNanos);
if (nanos > 999999999 || nanos < 0) {
throw new IllegalArgumentException("nanos field of an encoded timestamp in ORC must be between 0 and 999999999 inclusive, got " + nanos);
}

// the rounding error exists because java always rounds up when dividing integers
// -42001/1000 = -42; and -42001 % 1000 = -1 (+ 1000)
// to get the correct value we need
// (-42 - 1)*1000 + 999 = -42001
// (42)*1000 + 1 = 42001
if (millis < 0 && nanos != 0) {
millis -= 1000;
}
// Truncate nanos to millis and add to mills
return millis + (nanos / 1_000_000);
}

// This comes from the Apache Hive ORC code
private static int parseNanos(long serialized)
{
int zeros = ((int) serialized) & 0b111;
int result = (int) (serialized >>> 3);
if (zeros != 0) {
for (int i = 0; i <= zeros; ++i) {
result *= 10;
}
}
return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import static com.facebook.presto.orc.metadata.Stream.StreamKind.DATA;
import static com.facebook.presto.orc.metadata.Stream.StreamKind.PRESENT;
import static com.facebook.presto.orc.metadata.Stream.StreamKind.SECONDARY;
import static com.facebook.presto.orc.reader.ApacheHiveTimestampDecoder.decodeTimestamp;
import static com.facebook.presto.orc.stream.MissingInputStreamSource.missingStreamSource;
import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Verify.verify;
Expand Down Expand Up @@ -202,40 +203,6 @@ public String toString()
.toString();
}

// This comes from the Apache Hive ORC code
public static long decodeTimestamp(long seconds, long serializedNanos, long baseTimestampInSeconds)
{
long millis = (seconds + baseTimestampInSeconds) * MILLIS_PER_SECOND;
long nanos = parseNanos(serializedNanos);
if (nanos > 999999999 || nanos < 0) {
throw new IllegalArgumentException("nanos field of an encoded timestamp in ORC must be between 0 and 999999999 inclusive, got " + nanos);
}

// the rounding error exists because java always rounds up when dividing integers
// -42001/1000 = -42; and -42001 % 1000 = -1 (+ 1000)
// to get the correct value we need
// (-42 - 1)*1000 + 999 = -42001
// (42)*1000 + 1 = 42001
if (millis < 0 && nanos != 0) {
millis -= 1000;
}
// Truncate nanos to millis and add to mills
return millis + (nanos / 1_000_000);
}

// This comes from the Apache Hive ORC code
private static int parseNanos(long serialized)
{
int zeros = ((int) serialized) & 0b111;
int result = (int) (serialized >>> 3);
if (zeros != 0) {
for (int i = 0; i <= zeros; ++i) {
result *= 10;
}
}
return result;
}

@Override
public long getRetainedSizeInBytes()
{
Expand Down

0 comments on commit 36bc5fb

Please sign in to comment.