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