TestIndexedSort.java
上传用户:quxuerui
上传日期:2018-01-08
资源大小:41811k
文件大小:11k
- /**
- * 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.util;
- import java.io.IOException;
- import java.util.Arrays;
- import java.util.Random;
- import junit.framework.TestCase;
- import org.apache.hadoop.conf.Configuration;
- import org.apache.hadoop.io.DataInputBuffer;
- import org.apache.hadoop.io.DataOutputBuffer;
- import org.apache.hadoop.io.Text;
- import org.apache.hadoop.io.WritableComparator;
- public class TestIndexedSort extends TestCase {
- public void sortAllEqual(IndexedSorter sorter) throws Exception {
- final int SAMPLE = 500;
- int[] values = new int[SAMPLE];
- Arrays.fill(values, 10);
- SampleSortable s = new SampleSortable(values);
- sorter.sort(s, 0, SAMPLE);
- int[] check = s.getSorted();
- assertTrue(Arrays.toString(values) + "ndoesn't matchn" +
- Arrays.toString(check), Arrays.equals(values, check));
- // Set random min/max, re-sort.
- Random r = new Random();
- int min = r.nextInt(SAMPLE);
- int max = (min + 1 + r.nextInt(SAMPLE - 2)) % SAMPLE;
- values[min] = 9;
- values[max] = 11;
- System.out.println("testAllEqual setting min/max at " + min + "/" + max +
- "(" + sorter.getClass().getName() + ")");
- s = new SampleSortable(values);
- sorter.sort(s, 0, SAMPLE);
- check = s.getSorted();
- Arrays.sort(values);
- assertTrue(check[0] == 9);
- assertTrue(check[SAMPLE - 1] == 11);
- assertTrue(Arrays.toString(values) + "ndoesn't matchn" +
- Arrays.toString(check), Arrays.equals(values, check));
- }
- public void sortSorted(IndexedSorter sorter) throws Exception {
- final int SAMPLE = 500;
- int[] values = new int[SAMPLE];
- Random r = new Random();
- long seed = r.nextLong();
- r.setSeed(seed);
- System.out.println("testSorted seed: " + seed +
- "(" + sorter.getClass().getName() + ")");
- for (int i = 0; i < SAMPLE; ++i) {
- values[i] = r.nextInt(100);
- }
- Arrays.sort(values);
- SampleSortable s = new SampleSortable(values);
- sorter.sort(s, 0, SAMPLE);
- int[] check = s.getSorted();
- assertTrue(Arrays.toString(values) + "ndoesn't matchn" +
- Arrays.toString(check), Arrays.equals(values, check));
- }
- public void sortSequential(IndexedSorter sorter) throws Exception {
- final int SAMPLE = 500;
- int[] values = new int[SAMPLE];
- for (int i = 0; i < SAMPLE; ++i) {
- values[i] = i;
- }
- SampleSortable s = new SampleSortable(values);
- sorter.sort(s, 0, SAMPLE);
- int[] check = s.getSorted();
- assertTrue(Arrays.toString(values) + "ndoesn't matchn" +
- Arrays.toString(check), Arrays.equals(values, check));
- }
- public void sortSingleRecord(IndexedSorter sorter) throws Exception {
- final int SAMPLE = 1;
- SampleSortable s = new SampleSortable(SAMPLE);
- int[] values = s.getValues();
- sorter.sort(s, 0, SAMPLE);
- int[] check = s.getSorted();
- assertTrue(Arrays.toString(values) + "ndoesn't matchn" +
- Arrays.toString(check), Arrays.equals(values, check));
- }
- public void sortRandom(IndexedSorter sorter) throws Exception {
- final int SAMPLE = 256 * 1024;
- SampleSortable s = new SampleSortable(SAMPLE);
- long seed = s.getSeed();
- System.out.println("sortRandom seed: " + seed +
- "(" + sorter.getClass().getName() + ")");
- int[] values = s.getValues();
- Arrays.sort(values);
- sorter.sort(s, 0, SAMPLE);
- int[] check = s.getSorted();
- assertTrue("seed: " + seed + "ndoesn't matchn",
- Arrays.equals(values, check));
- }
- public void sortWritable(IndexedSorter sorter) throws Exception {
- final int SAMPLE = 1000;
- WritableSortable s = new WritableSortable(SAMPLE);
- long seed = s.getSeed();
- System.out.println("sortWritable seed: " + seed +
- "(" + sorter.getClass().getName() + ")");
- String[] values = s.getValues();
- Arrays.sort(values);
- sorter.sort(s, 0, SAMPLE);
- String[] check = s.getSorted();
- assertTrue("seed: " + seed + "ndoesn't match",
- Arrays.equals(values, check));
- }
- public void testQuickSort() throws Exception {
- QuickSort sorter = new QuickSort();
- sortRandom(sorter);
- sortSingleRecord(sorter);
- sortSequential(sorter);
- sortSorted(sorter);
- sortAllEqual(sorter);
- sortWritable(sorter);
- // test degenerate case for median-of-three partitioning
- // a_n, a_1, a_2, ..., a_{n-1}
- final int DSAMPLE = 500;
- int[] values = new int[DSAMPLE];
- for (int i = 0; i < DSAMPLE; ++i) { values[i] = i; }
- values[0] = values[DSAMPLE - 1] + 1;
- SampleSortable s = new SampleSortable(values);
- values = s.getValues();
- final int DSS = (DSAMPLE / 2) * (DSAMPLE / 2);
- // Worst case is (N/2)^2 comparisons, not including those effecting
- // the median-of-three partitioning; impl should handle this case
- MeasuredSortable m = new MeasuredSortable(s, DSS);
- sorter.sort(m, 0, DSAMPLE);
- System.out.println("QuickSort degen cmp/swp: " +
- m.getCmp() + "/" + m.getSwp() +
- "(" + sorter.getClass().getName() + ")");
- Arrays.sort(values);
- int[] check = s.getSorted();
- assertTrue(Arrays.equals(values, check));
- }
- public void testHeapSort() throws Exception {
- HeapSort sorter = new HeapSort();
- sortRandom(sorter);
- sortSingleRecord(sorter);
- sortSequential(sorter);
- sortSorted(sorter);
- sortAllEqual(sorter);
- sortWritable(sorter);
- }
- // Sortables //
- private static class SampleSortable implements IndexedSortable {
- private int[] valindex;
- private int[] valindirect;
- private int[] values;
- private final long seed;
- public SampleSortable() {
- this(50);
- }
- public SampleSortable(int j) {
- Random r = new Random();
- seed = r.nextLong();
- r.setSeed(seed);
- values = new int[j];
- valindex = new int[j];
- valindirect = new int[j];
- for (int i = 0; i < j; ++i) {
- valindex[i] = valindirect[i] = i;
- values[i] = r.nextInt(1000);
- }
- }
- public SampleSortable(int[] values) {
- this.values = values;
- valindex = new int[values.length];
- valindirect = new int[values.length];
- for (int i = 0; i < values.length; ++i) {
- valindex[i] = valindirect[i] = i;
- }
- seed = 0;
- }
- public long getSeed() {
- return seed;
- }
- public int compare(int i, int j) {
- // assume positive
- return
- values[valindirect[valindex[i]]] - values[valindirect[valindex[j]]];
- }
- public void swap(int i, int j) {
- int tmp = valindex[i];
- valindex[i] = valindex[j];
- valindex[j] = tmp;
- }
- public int[] getSorted() {
- int[] ret = new int[values.length];
- for (int i = 0; i < ret.length; ++i) {
- ret[i] = values[valindirect[valindex[i]]];
- }
- return ret;
- }
- public int[] getValues() {
- int[] ret = new int[values.length];
- System.arraycopy(values, 0, ret, 0, values.length);
- return ret;
- }
- }
- public static class MeasuredSortable implements IndexedSortable {
- private int comparisions;
- private int swaps;
- private final int maxcmp;
- private final int maxswp;
- private IndexedSortable s;
- public MeasuredSortable(IndexedSortable s) {
- this(s, Integer.MAX_VALUE);
- }
- public MeasuredSortable(IndexedSortable s, int maxcmp) {
- this(s, maxcmp, Integer.MAX_VALUE);
- }
- public MeasuredSortable(IndexedSortable s, int maxcmp, int maxswp) {
- this.s = s;
- this.maxcmp = maxcmp;
- this.maxswp = maxswp;
- }
- public int getCmp() { return comparisions; }
- public int getSwp() { return swaps; }
- public int compare(int i, int j) {
- assertTrue("Expected fewer than " + maxcmp + " comparisons",
- ++comparisions < maxcmp);
- return s.compare(i, j);
- }
- public void swap(int i, int j) {
- assertTrue("Expected fewer than " + maxswp + " swaps",
- ++swaps < maxswp);
- s.swap(i, j);
- }
- }
- private static class WritableSortable implements IndexedSortable {
- private static Random r = new Random();
- private final int eob;
- private final int[] indices;
- private final int[] offsets;
- private final byte[] bytes;
- private final WritableComparator comparator;
- private final String[] check;
- private final long seed;
- public WritableSortable() throws IOException {
- this(100);
- }
- public WritableSortable(int j) throws IOException {
- seed = r.nextLong();
- r.setSeed(seed);
- Text t = new Text();
- StringBuffer sb = new StringBuffer();
- indices = new int[j];
- offsets = new int[j];
- check = new String[j];
- DataOutputBuffer dob = new DataOutputBuffer();
- for (int i = 0; i < j; ++i) {
- indices[i] = i;
- offsets[i] = dob.getLength();
- genRandom(t, r.nextInt(15) + 1, sb);
- t.write(dob);
- check[i] = t.toString();
- }
- eob = dob.getLength();
- bytes = dob.getData();
- comparator = WritableComparator.get(Text.class);
- }
- public long getSeed() {
- return seed;
- }
- private static void genRandom(Text t, int len, StringBuffer sb) {
- sb.setLength(0);
- for (int i = 0; i < len; ++i) {
- sb.append(Integer.toString(r.nextInt(26) + 10, 36));
- }
- t.set(sb.toString());
- }
- public int compare(int i, int j) {
- final int ii = indices[i];
- final int ij = indices[j];
- return comparator.compare(bytes, offsets[ii],
- ((ii + 1 == indices.length) ? eob : offsets[ii + 1]) - offsets[ii],
- bytes, offsets[ij],
- ((ij + 1 == indices.length) ? eob : offsets[ij + 1]) - offsets[ij]);
- }
- public void swap(int i, int j) {
- int tmp = indices[i];
- indices[i] = indices[j];
- indices[j] = tmp;
- }
- public String[] getValues() {
- return check;
- }
- public String[] getSorted() throws IOException {
- String[] ret = new String[indices.length];
- Text t = new Text();
- DataInputBuffer dib = new DataInputBuffer();
- for (int i = 0; i < ret.length; ++i) {
- int ii = indices[i];
- dib.reset(bytes, offsets[ii],
- ((ii + 1 == indices.length) ? eob : offsets[ii + 1]) - offsets[ii]);
- t.readFields(dib);
- ret[i] = t.toString();
- }
- return ret;
- }
- }
- }