View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.omid.committable.hbase;
19  
20  import com.google.protobuf.CodedInputStream;
21  import com.google.protobuf.CodedOutputStream;
22  
23  import java.io.IOException;
24  
25  /**
26   * Contains implementations of the KeyGenerator interface
27   */
28  public class KeyGeneratorImplementations {
29  
30      public static KeyGenerator defaultKeyGenerator() {
31          return new BucketKeyGenerator();
32      }
33  
34      /**
35       * This is the used implementation
36       */
37      public static class BucketKeyGenerator implements KeyGenerator {
38  
39          @Override
40          public byte[] startTimestampToKey(long startTimestamp) throws IOException {
41              byte[] bytes = new byte[9];
42              bytes[0] = (byte) (startTimestamp & 0x0F);
43              bytes[1] = (byte) ((startTimestamp >> 56) & 0xFF);
44              bytes[2] = (byte) ((startTimestamp >> 48) & 0xFF);
45              bytes[3] = (byte) ((startTimestamp >> 40) & 0xFF);
46              bytes[4] = (byte) ((startTimestamp >> 32) & 0xFF);
47              bytes[5] = (byte) ((startTimestamp >> 24) & 0xFF);
48              bytes[6] = (byte) ((startTimestamp >> 16) & 0xFF);
49              bytes[7] = (byte) ((startTimestamp >> 8) & 0xFF);
50              bytes[8] = (byte) ((startTimestamp) & 0xFF);
51              return bytes;
52          }
53  
54          @Override
55          public long keyToStartTimestamp(byte[] key) {
56              assert (key.length == 9);
57              return ((long) key[1] & 0xFF) << 56
58                      | ((long) key[2] & 0xFF) << 48
59                      | ((long) key[3] & 0xFF) << 40
60                      | ((long) key[4] & 0xFF) << 32
61                      | ((long) key[5] & 0xFF) << 24
62                      | ((long) key[6] & 0xFF) << 16
63                      | ((long) key[7] & 0xFF) << 8
64                      | ((long) key[8] & 0xFF);
65          }
66  
67      }
68  
69      public static class FullRandomKeyGenerator implements KeyGenerator {
70  
71          @Override
72          public byte[] startTimestampToKey(long startTimestamp) {
73              assert startTimestamp >= 0;
74              // 1) Reverse the timestamp to better spread
75              long reversedStartTimestamp = Long.reverse(startTimestamp | Long.MIN_VALUE);
76              // 2) Convert to a byte array with big endian format
77              byte[] bytes = new byte[8];
78              bytes[0] = (byte) ((reversedStartTimestamp >> 56) & 0xFF);
79              bytes[1] = (byte) ((reversedStartTimestamp >> 48) & 0xFF);
80              bytes[2] = (byte) ((reversedStartTimestamp >> 40) & 0xFF);
81              bytes[3] = (byte) ((reversedStartTimestamp >> 32) & 0xFF);
82              bytes[4] = (byte) ((reversedStartTimestamp >> 24) & 0xFF);
83              bytes[5] = (byte) ((reversedStartTimestamp >> 16) & 0xFF);
84              bytes[6] = (byte) ((reversedStartTimestamp >> 8) & 0xFF);
85              bytes[7] = (byte) ((reversedStartTimestamp) & 0xFE);
86              return bytes;
87          }
88  
89          @Override
90          public long keyToStartTimestamp(byte[] key) {
91              assert (key.length == 8);
92              // 1) Convert from big endian each byte
93              long startTimestamp = ((long) key[0] & 0xFF) << 56
94                      | ((long) key[1] & 0xFF) << 48
95                      | ((long) key[2] & 0xFF) << 40
96                      | ((long) key[3] & 0xFF) << 32
97                      | ((long) key[4] & 0xFF) << 24
98                      | ((long) key[5] & 0xFF) << 16
99                      | ((long) key[6] & 0xFF) << 8
100                     | ((long) key[7] & 0xFF);
101             // 2) Reverse to obtain the original value
102             return Long.reverse(startTimestamp);
103         }
104     }
105 
106     public static class BadRandomKeyGenerator implements KeyGenerator {
107 
108         @Override
109         public byte[] startTimestampToKey(long startTimestamp) throws IOException {
110             long reversedStartTimestamp = Long.reverse(startTimestamp);
111             byte[] bytes = new byte[CodedOutputStream.computeSFixed64SizeNoTag(reversedStartTimestamp)];
112             CodedOutputStream cos = CodedOutputStream.newInstance(bytes);
113             cos.writeSFixed64NoTag(reversedStartTimestamp);
114             cos.flush();
115             return bytes;
116         }
117 
118         @Override
119         public long keyToStartTimestamp(byte[] key) throws IOException {
120             CodedInputStream cis = CodedInputStream.newInstance(key);
121             return Long.reverse(cis.readSFixed64());
122         }
123 
124     }
125 
126     public static class SeqKeyGenerator implements KeyGenerator {
127 
128         @Override
129         public byte[] startTimestampToKey(long startTimestamp) throws IOException {
130             // Convert to a byte array with big endian format
131             byte[] bytes = new byte[8];
132 
133             bytes[0] = (byte) ((startTimestamp >> 56) & 0xFF);
134             bytes[1] = (byte) ((startTimestamp >> 48) & 0xFF);
135             bytes[2] = (byte) ((startTimestamp >> 40) & 0xFF);
136             bytes[3] = (byte) ((startTimestamp >> 32) & 0xFF);
137             bytes[4] = (byte) ((startTimestamp >> 24) & 0xFF);
138             bytes[5] = (byte) ((startTimestamp >> 16) & 0xFF);
139             bytes[6] = (byte) ((startTimestamp >> 8) & 0xFF);
140             bytes[7] = (byte) ((startTimestamp) & 0xFF);
141             return bytes;
142         }
143 
144         @Override
145         public long keyToStartTimestamp(byte[] key) {
146             assert (key.length == 8);
147             // Convert from big endian each byte
148             return ((long) key[0] & 0xFF) << 56
149                     | ((long) key[1] & 0xFF) << 48
150                     | ((long) key[2] & 0xFF) << 40
151                     | ((long) key[3] & 0xFF) << 32
152                     | ((long) key[4] & 0xFF) << 24
153                     | ((long) key[5] & 0xFF) << 16
154                     | ((long) key[6] & 0xFF) << 8
155                     | ((long) key[7] & 0xFF);
156         }
157 
158     }
159 
160 }