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  ASCENDING {
031    @Override
032    public int cmp(int cmp) {
033      /* noop */ return cmp;
034    }
035
036    @Override
037    public byte apply(byte val) {
038      /* noop */ return val;
039    }
040
041    @Override
042    public void apply(byte[] val) {
043      /* noop */
044    }
045
046    @Override
047    public void apply(byte[] val, int offset, int length) {
048      /* noop */
049    }
050
051    @Override
052    public String toString() {
053      return "ASCENDING";
054    }
055  },
056
057  DESCENDING {
058    /**
059     * A {@code byte} value is inverted by taking its 1's Complement, achieved
060     * via {@code xor} with {@code 0xff}.
061     */
062    private static final byte MASK = (byte) 0xff;
063
064    @Override
065    public int cmp(int cmp) {
066      return -1 * cmp;
067    }
068
069    @Override
070    public byte apply(byte val) {
071      return (byte) (val ^ MASK);
072    }
073
074    @Override
075    public void apply(byte[] val) {
076      for (int i = 0; i < val.length; i++) {
077        val[i] ^= MASK;
078      }
079    }
080
081    @Override
082    public void apply(byte[] val, int offset, int length) {
083      for (int i = 0; i < length; i++) {
084        val[offset + i] ^= MASK;
085      }
086    }
087
088    @Override
089    public String toString() {
090      return "DESCENDING";
091    }
092  };
093
094  /**
095   * Returns the adjusted trichotomous value according to the ordering imposed by this
096   * {@code Order}.
097   */
098  public abstract int cmp(int cmp);
099
100  /**
101   * Apply order to the byte {@code val}.
102   */
103  public abstract byte apply(byte val);
104
105  /**
106   * Apply order to the byte array {@code val}.
107   */
108  public abstract void apply(byte[] val);
109
110  /**
111   * Apply order to a range within the byte array {@code val}.
112   */
113  public abstract void apply(byte[] val, int offset, int length);
114}