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.KeyValue;
31 import org.apache.hadoop.hbase.util.Bytes;
32 import org.apache.hadoop.hbase.util.FSUtils;
33 import org.apache.hadoop.io.Writable;
34
35 /**
36 * A reference to the top or bottom half of a store file. The file referenced
37 * lives under a different region. References are made at region split time.
38 *
39 * <p>References work with a special half store file type. References know how
40 * to write out the reference format in the file system and are whats juggled
41 * when references are mixed in with direct store files. The half store file
42 * type is used reading the referred to file.
43 *
44 * <p>References to store files located over in some other region look like
45 * this in the file system
46 * <code>1278437856009925445.3323223323</code>:
47 * i.e. an id followed by hash of the referenced region.
48 * Note, a region is itself not splitable if it has instances of store file
49 * references. References are cleaned up by compactions.
50 */
51 public class Reference implements Writable {
52 private byte [] splitkey;
53 private Range region;
54
55 /**
56 * For split HStoreFiles, it specifies if the file covers the lower half or
57 * the upper half of the key range
58 */
59 public static enum Range {
60 /** HStoreFile contains upper half of key range */
61 top,
62 /** HStoreFile contains lower half of key range */
63 bottom
64 }
65
66 /**
67 * Constructor
68 * @param splitRow This is row we are splitting around.
69 * @param fr
70 */
71 public Reference(final byte [] splitRow, final Range fr) {
72 this.splitkey = splitRow == null?
73 null: KeyValue.createFirstOnRow(splitRow).getKey();
74 this.region = fr;
75 }
76
77 /**
78 * Used by serializations.
79 */
80 public Reference() {
81 this(null, Range.bottom);
82 }
83
84 /**
85 *
86 * @return Range
87 */
88 public Range getFileRegion() {
89 return this.region;
90 }
91
92 /**
93 * @return splitKey
94 */
95 public byte [] getSplitKey() {
96 return splitkey;
97 }
98
99 /**
100 * @see java.lang.Object#toString()
101 */
102 @Override
103 public String toString() {
104 return "" + this.region;
105 }
106
107 // Make it serializable.
108
109 public void write(DataOutput out) throws IOException {
110 // Write true if we're doing top of the file.
111 out.writeBoolean(isTopFileRegion(this.region));
112 Bytes.writeByteArray(out, this.splitkey);
113 }
114
115 public void readFields(DataInput in) throws IOException {
116 boolean tmp = in.readBoolean();
117 // If true, set region to top.
118 this.region = tmp? Range.top: Range.bottom;
119 this.splitkey = Bytes.readByteArray(in);
120 }
121
122 public static boolean isTopFileRegion(final Range r) {
123 return r.equals(Range.top);
124 }
125
126 public Path write(final FileSystem fs, final Path p)
127 throws IOException {
128 FSUtils.create(fs, p);
129 FSDataOutputStream out = fs.create(p);
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 }