From 789e587c70bbd544908c1ac10b88a7bcff77f932 Mon Sep 17 00:00:00 2001 From: Junegunn Choi Date: Thu, 30 Jun 2016 16:26:47 +0900 Subject: [PATCH] HBASE-16106 Fix RowSpec timestamp interpretation --- .../java/org/apache/hadoop/hbase/rest/RowSpec.java | 25 ++++---- .../org/apache/hadoop/hbase/rest/TestRowSpec.java | 70 ++++++++++++++++++++++ 2 files changed, 83 insertions(+), 12 deletions(-) create mode 100644 hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestRowSpec.java diff --git a/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/RowSpec.java b/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/RowSpec.java index cc51c85..f30bc6c 100644 --- a/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/RowSpec.java +++ b/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/RowSpec.java @@ -151,7 +151,7 @@ public class RowSpec { if (i >= path.length()) { return i; } - long time0 = 0, time1 = 0; + List timestamps = new ArrayList(2); try { char c = 0; StringBuilder stamp = new StringBuilder(); @@ -164,8 +164,8 @@ public class RowSpec { i++; } try { - time0 = Long.parseLong(URLDecoder.decode(stamp.toString(), - HConstants.UTF8_ENCODING)); + timestamps.add(stamp.length() == 0 ? DEFAULT_START_TIMESTAMP : + Long.parseLong(URLDecoder.decode(stamp.toString(), HConstants.UTF8_ENCODING))); } catch (NumberFormatException e) { throw new IllegalArgumentException(e); } @@ -177,8 +177,8 @@ public class RowSpec { i++; } try { - time1 = Long.parseLong(URLDecoder.decode(stamp.toString(), - HConstants.UTF8_ENCODING)); + timestamps.add(stamp.length() == 0 ? DEFAULT_END_TIMESTAMP : + Long.parseLong(URLDecoder.decode(stamp.toString(), HConstants.UTF8_ENCODING))); } catch (NumberFormatException e) { throw new IllegalArgumentException(e); } @@ -192,11 +192,12 @@ public class RowSpec { // shouldn't happen throw new RuntimeException(e); } - if (time1 != 0) { - startTime = time0; - endTime = time1; - } else { - endTime = time0; + if (timestamps.size() == 1) { + startTime = timestamps.get(0); + endTime = timestamps.get(0) + 1; + } else if (timestamps.size() == 2) { + startTime = timestamps.get(0); + endTime = timestamps.get(1); } return i; } @@ -354,11 +355,11 @@ public class RowSpec { } public boolean hasTimestamp() { - return (startTime == 0) && (endTime != Long.MAX_VALUE); + return startTime != DEFAULT_START_TIMESTAMP && endTime == startTime + 1; } public long getTimestamp() { - return endTime; + return startTime; } public long getStartTime() { diff --git a/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestRowSpec.java b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestRowSpec.java new file mode 100644 index 0000000..13f2330 --- /dev/null +++ b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestRowSpec.java @@ -0,0 +1,70 @@ +/** + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hadoop.hbase.rest; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.apache.hadoop.hbase.testclassification.RestTests; +import org.apache.hadoop.hbase.testclassification.SmallTests; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +@Category({RestTests.class, SmallTests.class}) +public class TestRowSpec { + @Test + public void testTimestamp() { + final long timestamp = 1000000000000L; + RowSpec spec = new RowSpec("rowkey/cf:cq/" + timestamp); + + assertEquals(timestamp, spec.getStartTime()); + assertEquals(timestamp + 1, spec.getEndTime()); + + assertTrue(spec.hasTimestamp()); + assertEquals(timestamp, spec.getTimestamp()); + } + + @Test + public void testTimestampRange() { + final long startTime = 1000000000000L; + final long endTime = 1100000000000L; + + RowSpec spec = new RowSpec("rowkey/cf:cq/" + startTime + "," + endTime); + assertEquals(startTime, spec.getStartTime()); + assertEquals(endTime, spec.getEndTime()); + assertFalse(spec.hasTimestamp()); + + // Open-ended ranges + spec = new RowSpec("rowkey/cf:cq/" + startTime + ","); + assertEquals(startTime, spec.getStartTime()); + assertEquals(RowSpec.DEFAULT_END_TIMESTAMP, spec.getEndTime()); + assertFalse(spec.hasTimestamp()); + + spec = new RowSpec("rowkey/cf:cq/," + endTime); + assertEquals(RowSpec.DEFAULT_START_TIMESTAMP, spec.getStartTime()); + assertEquals(endTime, spec.getEndTime()); + assertFalse(spec.hasTimestamp()); + + spec = new RowSpec("rowkey/cf:cq/,"); + assertEquals(RowSpec.DEFAULT_START_TIMESTAMP, spec.getStartTime()); + assertEquals(RowSpec.DEFAULT_END_TIMESTAMP, spec.getEndTime()); + assertFalse(spec.hasTimestamp()); + } +} -- 2.6.3