blob: 34dcaa16d075b9d3423fb1c0136476a3b35736b5 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.io.file.tfile;
import java.io.IOException;
import java.util.Random;
import junit.framework.Assert;
import junit.framework.TestCase;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
public class TestVLong extends TestCase {
private static String ROOT =
System.getProperty("test.build.data", "/tmp/tfile-test");
private Configuration conf;
private FileSystem fs;
private Path path;
private String outputFile = "TestVLong";
@Override
public void setUp() throws IOException {
conf = new Configuration();
path = new Path(ROOT, outputFile);
fs = path.getFileSystem(conf);
if (fs.exists(path)) {
fs.delete(path, false);
}
}
@Override
public void tearDown() throws IOException {
if (fs.exists(path)) {
fs.delete(path, false);
}
}
public void testVLongByte() throws IOException {
FSDataOutputStream out = fs.create(path);
for (int i = Byte.MIN_VALUE; i <= Byte.MAX_VALUE; ++i) {
Utils.writeVLong(out, i);
}
out.close();
Assert.assertEquals("Incorrect encoded size", (1 << Byte.SIZE) + 96, fs
.getFileStatus(
path).getLen());
FSDataInputStream in = fs.open(path);
for (int i = Byte.MIN_VALUE; i <= Byte.MAX_VALUE; ++i) {
long n = Utils.readVLong(in);
Assert.assertEquals(n, i);
}
in.close();
fs.delete(path, false);
}
private long writeAndVerify(int shift) throws IOException {
FSDataOutputStream out = fs.create(path);
for (int i = Short.MIN_VALUE; i <= Short.MAX_VALUE; ++i) {
Utils.writeVLong(out, ((long) i) << shift);
}
out.close();
FSDataInputStream in = fs.open(path);
for (int i = Short.MIN_VALUE; i <= Short.MAX_VALUE; ++i) {
long n = Utils.readVLong(in);
Assert.assertEquals(n, ((long) i) << shift);
}
in.close();
long ret = fs.getFileStatus(path).getLen();
fs.delete(path, false);
return ret;
}
public void testVLongShort() throws IOException {
long size = writeAndVerify(0);
Assert.assertEquals("Incorrect encoded size", (1 << Short.SIZE) * 2
+ ((1 << Byte.SIZE) - 40)
* (1 << Byte.SIZE) - 128 - 32, size);
}
public void testVLong3Bytes() throws IOException {
long size = writeAndVerify(Byte.SIZE);
Assert.assertEquals("Incorrect encoded size", (1 << Short.SIZE) * 3
+ ((1 << Byte.SIZE) - 32) * (1 << Byte.SIZE) - 40 - 1, size);
}
public void testVLong4Bytes() throws IOException {
long size = writeAndVerify(Byte.SIZE * 2);
Assert.assertEquals("Incorrect encoded size", (1 << Short.SIZE) * 4
+ ((1 << Byte.SIZE) - 16) * (1 << Byte.SIZE) - 32 - 2, size);
}
public void testVLong5Bytes() throws IOException {
long size = writeAndVerify(Byte.SIZE * 3);
Assert.assertEquals("Incorrect encoded size", (1 << Short.SIZE) * 6 - 256
- 16 - 3, size);
}
private void verifySixOrMoreBytes(int bytes) throws IOException {
long size = writeAndVerify(Byte.SIZE * (bytes - 2));
Assert.assertEquals("Incorrect encoded size", (1 << Short.SIZE)
* (bytes + 1) - 256 - bytes + 1, size);
}
public void testVLong6Bytes() throws IOException {
verifySixOrMoreBytes(6);
}
public void testVLong7Bytes() throws IOException {
verifySixOrMoreBytes(7);
}
public void testVLong8Bytes() throws IOException {
verifySixOrMoreBytes(8);
}
public void testVLongRandom() throws IOException {
int count = 1024 * 1024;
long data[] = new long[count];
Random rng = new Random();
for (int i = 0; i < data.length; ++i) {
int shift = rng.nextInt(Long.SIZE) + 1;
long mask = (1L << shift) - 1;
long a = ((long) rng.nextInt()) << 32;
long b = ((long) rng.nextInt()) & 0xffffffffL;
data[i] = (a + b) & mask;
}
FSDataOutputStream out = fs.create(path);
for (int i = 0; i < data.length; ++i) {
Utils.writeVLong(out, data[i]);
}
out.close();
FSDataInputStream in = fs.open(path);
for (int i = 0; i < data.length; ++i) {
Assert.assertEquals(Utils.readVLong(in), data[i]);
}
in.close();
fs.delete(path, false);
}
}