001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.types;
019
020import static org.junit.jupiter.api.Assertions.assertEquals;
021
022import org.apache.hadoop.hbase.testclassification.MiscTests;
023import org.apache.hadoop.hbase.testclassification.SmallTests;
024import org.apache.hadoop.hbase.util.Order;
025import org.apache.hadoop.hbase.util.PositionedByteRange;
026import org.apache.hadoop.hbase.util.SimplePositionedMutableByteRange;
027import org.junit.jupiter.api.Tag;
028import org.junit.jupiter.api.Test;
029
030@Tag(MiscTests.TAG)
031@Tag(SmallTests.TAG)
032public class TestUnion2 {
033  /**
034   * An example <code>Union</code>
035   */
036  private static class SampleUnion1 extends Union2<Integer, String> {
037    private static final byte IS_INTEGER = 0x00;
038    private static final byte IS_STRING = 0x01;
039
040    public SampleUnion1() {
041      super(new RawInteger(), new RawStringTerminated(Order.DESCENDING, "."));
042    }
043
044    @Override
045    public int skip(PositionedByteRange src) {
046      switch (src.get()) {
047        case IS_INTEGER:
048          return 1 + typeA.skip(src);
049        case IS_STRING:
050          return 1 + typeB.skip(src);
051        default:
052          throw new IllegalArgumentException("Unrecognized encoding format.");
053      }
054    }
055
056    @Override
057    public Object decode(PositionedByteRange src) {
058      switch (src.get()) {
059        case IS_INTEGER:
060          return typeA.decode(src);
061        case IS_STRING:
062          return typeB.decode(src);
063        default:
064          throw new IllegalArgumentException("Unrecognized encoding format.");
065      }
066    }
067
068    @Override
069    public int encodedLength(Object val) {
070      Integer i = null;
071      String s = null;
072      if (val instanceof Integer) {
073        i = (Integer) val;
074      }
075      if (val instanceof String) {
076        s = (String) val;
077      }
078      if (null != i) {
079        return 1 + typeA.encodedLength(i);
080      }
081
082      if (null != s) {
083        return 1 + typeB.encodedLength(s);
084      }
085      throw new IllegalArgumentException("val is not a valid member of this union.");
086    }
087
088    @Override
089    public int encode(PositionedByteRange dst, Object val) {
090      Integer i = null;
091      String s = null;
092      if (val instanceof Integer) {
093        i = (Integer) val;
094      }
095      if (val instanceof String) {
096        s = (String) val;
097      }
098      if (null != i) {
099        dst.put(IS_INTEGER);
100        return 1 + typeA.encode(dst, i);
101      } else if (null != s) {
102        dst.put(IS_STRING);
103        return 1 + typeB.encode(dst, s);
104      } else {
105        throw new IllegalArgumentException("val is not of a supported type.");
106      }
107    }
108  }
109
110  @Test
111  public void testEncodeDecode() {
112    Integer intVal = 10;
113    String strVal = "hello";
114    PositionedByteRange buff = new SimplePositionedMutableByteRange(10);
115    SampleUnion1 type = new SampleUnion1();
116
117    type.encode(buff, intVal);
118    buff.setPosition(0);
119    assertEquals(0, intVal.compareTo(type.decodeA(buff)));
120    buff.setPosition(0);
121    type.encode(buff, strVal);
122    buff.setPosition(0);
123    assertEquals(0, strVal.compareTo(type.decodeB(buff)));
124  }
125
126  @Test
127  public void testSkip() {
128    Integer intVal = 10;
129    String strVal = "hello";
130    PositionedByteRange buff = new SimplePositionedMutableByteRange(10);
131    SampleUnion1 type = new SampleUnion1();
132
133    int len = type.encode(buff, intVal);
134    buff.setPosition(0);
135    assertEquals(len, type.skip(buff));
136    buff.setPosition(0);
137    len = type.encode(buff, strVal);
138    buff.setPosition(0);
139    assertEquals(len, type.skip(buff));
140  }
141}