1 /**
2 * Copyright 2008 The Apache Software Foundation
3 *
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20 package org.apache.hadoop.hbase.io;
21
22 import java.io.DataInput;
23 import java.io.DataOutput;
24 import java.io.IOException;
25
26 import org.apache.hadoop.fs.FSDataInputStream;
27 import org.apache.hadoop.fs.FSDataOutputStream;
28 import org.apache.hadoop.fs.FileSystem;
29 import org.apache.hadoop.fs.Path;
30 import org.apache.hadoop.hbase.HBaseFileSystem;
31 import org.apache.hadoop.hbase.KeyValue;
32 import org.apache.hadoop.hbase.util.Bytes;
33 import org.apache.hadoop.hbase.util.FSUtils;
34 import org.apache.hadoop.io.Writable;
35
36 /**
37 * A reference to the top or bottom half of a store file. The file referenced
38 * lives under a different region. References are made at region split time.
39 *
40 * <p>References work with a special half store file type. References know how
41 * to write out the reference format in the file system and are whats juggled
42 * when references are mixed in with direct store files. The half store file
43 * type is used reading the referred to file.
44 *
45 * <p>References to store files located over in some other region look like
46 * this in the file system
47 * <code>1278437856009925445.3323223323</code>:
48 * i.e. an id followed by hash of the referenced region.
49 * Note, a region is itself not splitable if it has instances of store file
50 * references. References are cleaned up by compactions.
51 */
52 public class Reference implements Writable {
53 private byte [] splitkey;
54 private Range region;
55
56 /**
57 * For split HStoreFiles, it specifies if the file covers the lower half or
58 * the upper half of the key range
59 */
60 public static enum Range {
61 /** HStoreFile contains upper half of key range */
62 top,
63 /** HStoreFile contains lower half of key range */
64 bottom
65 }
66
67 /**
68 * Constructor
69 * @param splitRow This is row we are splitting around.
70 * @param fr
71 */
72 public Reference(final byte [] splitRow, final Range fr) {
73 this.splitkey = splitRow == null?
74 null: KeyValue.createFirstOnRow(splitRow).getKey();
75 this.region = fr;
76 }
77
78 /**
79 * Used by serializations.
80 */
81 public Reference() {
82 this(null, Range.bottom);
83 }
84
85 /**
86 *
87 * @return Range
88 */
89 public Range getFileRegion() {
90 return this.region;
91 }
92
93 /**
94 * @return splitKey
95 */
96 public byte [] getSplitKey() {
97 return splitkey;
98 }
99
100 /**
101 * @see java.lang.Object#toString()
102 */
103 @Override
104 public String toString() {
105 return "" + this.region;
106 }
107
108 // Make it serializable.
109
110 public void write(DataOutput out) throws IOException {
111 // Write true if we're doing top of the file.
112 out.writeBoolean(isTopFileRegion(this.region));
113 Bytes.writeByteArray(out, this.splitkey);
114 }
115
116 public void readFields(DataInput in) throws IOException {
117 boolean tmp = in.readBoolean();
118 // If true, set region to top.
119 this.region = tmp? Range.top: Range.bottom;
120 this.splitkey = Bytes.readByteArray(in);
121 }
122
123 public static boolean isTopFileRegion(final Range r) {
124 return r.equals(Range.top);
125 }
126
127 public Path write(final FileSystem fs, final Path p)
128 throws IOException {
129 FSDataOutputStream out = HBaseFileSystem.createPathOnFileSystem(fs, p, false);
130 try {
131 write(out);
132 } finally {
133 out.close();
134 }
135 return p;
136 }
137
138 /**
139 * Read a Reference from FileSystem.
140 * @param fs
141 * @param p
142 * @return New Reference made from passed <code>p</code>
143 * @throws IOException
144 */
145 public static Reference read(final FileSystem fs, final Path p)
146 throws IOException {
147 FSDataInputStream in = fs.open(p);
148 try {
149 Reference r = new Reference();
150 r.readFields(in);
151 return r;
152 } finally {
153 in.close();
154 }
155 }
156 }