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.util;
019
020import org.apache.yetus.audience.InterfaceAudience;
021
022/**
023 * Used to describe or modify the lexicographical sort order of a
024 * {@code byte[]}. Default ordering is considered {@code ASCENDING}. The order
025 * of a {@code byte[]} can be inverted, resulting in {@code DESCENDING} order,
026 * by replacing each byte with its 1's compliment.
027 */
028@InterfaceAudience.Public
029public enum Order {
030
031  ASCENDING {
032    @Override
033    public int cmp(int cmp) { /* noop */ return cmp; }
034
035    @Override
036    public byte apply(byte val) { /* noop */ return val; }
037
038    @Override
039    public void apply(byte[] val) { /* noop */ }
040
041    @Override
042    public void apply(byte[] val, int offset, int length) { /* noop */ }
043
044    @Override
045    public String toString() { return "ASCENDING"; }
046  },
047
048  DESCENDING {
049    /**
050     * A {@code byte} value is inverted by taking its 1's Complement, achieved
051     * via {@code xor} with {@code 0xff}.
052     */
053    private static final byte MASK = (byte) 0xff;
054
055    @Override
056    public int cmp(int cmp) { return -1 * cmp; }
057
058    @Override
059    public byte apply(byte val) { return (byte) (val ^ MASK); }
060
061    @Override
062    public void apply(byte[] val) {
063      for (int i = 0; i < val.length; i++) { val[i] ^= MASK; }
064    }
065
066    @Override
067    public void apply(byte[] val, int offset, int length) {
068      for (int i = 0; i < length; i++) { val[offset + i] ^= MASK; }
069    }
070
071    @Override
072    public String toString() { return "DESCENDING"; }
073  };
074
075  /**
076   * Returns the adjusted trichotomous value according to the ordering imposed by this
077   * {@code Order}.
078   */
079  public abstract int cmp(int cmp);
080
081  /**
082   * Apply order to the byte {@code val}.
083   */
084  public abstract byte apply(byte val);
085
086  /**
087   * Apply order to the byte array {@code val}.
088   */
089  public abstract void apply(byte[] val);
090
091  /**
092   * Apply order to a range within the byte array {@code val}.
093   */
094  public abstract void apply(byte[] val, int offset, int length);
095}