TestIndexedSort.java
上传用户:quxuerui
上传日期:2018-01-08
资源大小:41811k
文件大小:11k
源码类别:

网格计算

开发平台:

Java

  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.hadoop.util;
  19. import java.io.IOException;
  20. import java.util.Arrays;
  21. import java.util.Random;
  22. import junit.framework.TestCase;
  23. import org.apache.hadoop.conf.Configuration;
  24. import org.apache.hadoop.io.DataInputBuffer;
  25. import org.apache.hadoop.io.DataOutputBuffer;
  26. import org.apache.hadoop.io.Text;
  27. import org.apache.hadoop.io.WritableComparator;
  28. public class TestIndexedSort extends TestCase {
  29.   public void sortAllEqual(IndexedSorter sorter) throws Exception {
  30.     final int SAMPLE = 500;
  31.     int[] values = new int[SAMPLE];
  32.     Arrays.fill(values, 10);
  33.     SampleSortable s = new SampleSortable(values);
  34.     sorter.sort(s, 0, SAMPLE);
  35.     int[] check = s.getSorted();
  36.     assertTrue(Arrays.toString(values) + "ndoesn't matchn" +
  37.         Arrays.toString(check), Arrays.equals(values, check));
  38.     // Set random min/max, re-sort.
  39.     Random r = new Random();
  40.     int min = r.nextInt(SAMPLE);
  41.     int max = (min + 1 + r.nextInt(SAMPLE - 2)) % SAMPLE;
  42.     values[min] = 9;
  43.     values[max] = 11;
  44.     System.out.println("testAllEqual setting min/max at " + min + "/" + max +
  45.         "(" + sorter.getClass().getName() + ")");
  46.     s = new SampleSortable(values);
  47.     sorter.sort(s, 0, SAMPLE);
  48.     check = s.getSorted();
  49.     Arrays.sort(values);
  50.     assertTrue(check[0] == 9);
  51.     assertTrue(check[SAMPLE - 1] == 11);
  52.     assertTrue(Arrays.toString(values) + "ndoesn't matchn" +
  53.         Arrays.toString(check), Arrays.equals(values, check));
  54.   }
  55.   public void sortSorted(IndexedSorter sorter) throws Exception {
  56.     final int SAMPLE = 500;
  57.     int[] values = new int[SAMPLE];
  58.     Random r = new Random();
  59.     long seed = r.nextLong();
  60.     r.setSeed(seed);
  61.     System.out.println("testSorted seed: " + seed +
  62.         "(" + sorter.getClass().getName() + ")");
  63.     for (int i = 0; i < SAMPLE; ++i) {
  64.       values[i] = r.nextInt(100);
  65.     }
  66.     Arrays.sort(values);
  67.     SampleSortable s = new SampleSortable(values);
  68.     sorter.sort(s, 0, SAMPLE);
  69.     int[] check = s.getSorted();
  70.     assertTrue(Arrays.toString(values) + "ndoesn't matchn" +
  71.         Arrays.toString(check), Arrays.equals(values, check));
  72.   }
  73.   public void sortSequential(IndexedSorter sorter) throws Exception {
  74.     final int SAMPLE = 500;
  75.     int[] values = new int[SAMPLE];
  76.     for (int i = 0; i < SAMPLE; ++i) {
  77.       values[i] = i;
  78.     }
  79.     SampleSortable s = new SampleSortable(values);
  80.     sorter.sort(s, 0, SAMPLE);
  81.     int[] check = s.getSorted();
  82.     assertTrue(Arrays.toString(values) + "ndoesn't matchn" +
  83.         Arrays.toString(check), Arrays.equals(values, check));
  84.   }
  85.   public void sortSingleRecord(IndexedSorter sorter) throws Exception {
  86.     final int SAMPLE = 1;
  87.     SampleSortable s = new SampleSortable(SAMPLE);
  88.     int[] values = s.getValues();
  89.     sorter.sort(s, 0, SAMPLE);
  90.     int[] check = s.getSorted();
  91.     assertTrue(Arrays.toString(values) + "ndoesn't matchn" +
  92.         Arrays.toString(check), Arrays.equals(values, check));
  93.   }
  94.   public void sortRandom(IndexedSorter sorter) throws Exception {
  95.     final int SAMPLE = 256 * 1024;
  96.     SampleSortable s = new SampleSortable(SAMPLE);
  97.     long seed = s.getSeed();
  98.     System.out.println("sortRandom seed: " + seed +
  99.         "(" + sorter.getClass().getName() + ")");
  100.     int[] values = s.getValues();
  101.     Arrays.sort(values);
  102.     sorter.sort(s, 0, SAMPLE);
  103.     int[] check = s.getSorted();
  104.     assertTrue("seed: " + seed + "ndoesn't matchn",
  105.                Arrays.equals(values, check));
  106.   }
  107.   public void sortWritable(IndexedSorter sorter) throws Exception {
  108.     final int SAMPLE = 1000;
  109.     WritableSortable s = new WritableSortable(SAMPLE);
  110.     long seed = s.getSeed();
  111.     System.out.println("sortWritable seed: " + seed +
  112.         "(" + sorter.getClass().getName() + ")");
  113.     String[] values = s.getValues();
  114.     Arrays.sort(values);
  115.     sorter.sort(s, 0, SAMPLE);
  116.     String[] check = s.getSorted();
  117.     assertTrue("seed: " + seed + "ndoesn't match",
  118.                Arrays.equals(values, check));
  119.   }
  120.   public void testQuickSort() throws Exception {
  121.     QuickSort sorter = new QuickSort();
  122.     sortRandom(sorter);
  123.     sortSingleRecord(sorter);
  124.     sortSequential(sorter);
  125.     sortSorted(sorter);
  126.     sortAllEqual(sorter);
  127.     sortWritable(sorter);
  128.     // test degenerate case for median-of-three partitioning
  129.     // a_n, a_1, a_2, ..., a_{n-1}
  130.     final int DSAMPLE = 500;
  131.     int[] values = new int[DSAMPLE];
  132.     for (int i = 0; i < DSAMPLE; ++i) { values[i] = i; }
  133.     values[0] = values[DSAMPLE - 1] + 1;
  134.     SampleSortable s = new SampleSortable(values);
  135.     values = s.getValues();
  136.     final int DSS = (DSAMPLE / 2) * (DSAMPLE / 2);
  137.     // Worst case is (N/2)^2 comparisons, not including those effecting
  138.     // the median-of-three partitioning; impl should handle this case
  139.     MeasuredSortable m = new MeasuredSortable(s, DSS);
  140.     sorter.sort(m, 0, DSAMPLE);
  141.     System.out.println("QuickSort degen cmp/swp: " +
  142.         m.getCmp() + "/" + m.getSwp() +
  143.         "(" + sorter.getClass().getName() + ")");
  144.     Arrays.sort(values);
  145.     int[] check = s.getSorted();
  146.     assertTrue(Arrays.equals(values, check));
  147.   }
  148.   public void testHeapSort() throws Exception {
  149.     HeapSort sorter = new HeapSort();
  150.     sortRandom(sorter);
  151.     sortSingleRecord(sorter);
  152.     sortSequential(sorter);
  153.     sortSorted(sorter);
  154.     sortAllEqual(sorter);
  155.     sortWritable(sorter);
  156.   }
  157.   // Sortables //
  158.   private static class SampleSortable implements IndexedSortable {
  159.     private int[] valindex;
  160.     private int[] valindirect;
  161.     private int[] values;
  162.     private final long seed;
  163.     public SampleSortable() {
  164.       this(50);
  165.     }
  166.     public SampleSortable(int j) {
  167.       Random r = new Random();
  168.       seed = r.nextLong();
  169.       r.setSeed(seed);
  170.       values = new int[j];
  171.       valindex = new int[j];
  172.       valindirect = new int[j];
  173.       for (int i = 0; i < j; ++i) {
  174.         valindex[i] = valindirect[i] = i;
  175.         values[i] = r.nextInt(1000);
  176.       }
  177.     }
  178.     public SampleSortable(int[] values) {
  179.       this.values = values;
  180.       valindex = new int[values.length];
  181.       valindirect = new int[values.length];
  182.       for (int i = 0; i < values.length; ++i) {
  183.         valindex[i] = valindirect[i] = i;
  184.       }
  185.       seed = 0;
  186.     }
  187.     public long getSeed() {
  188.       return seed;
  189.     }
  190.     public int compare(int i, int j) {
  191.       // assume positive
  192.       return
  193.         values[valindirect[valindex[i]]] - values[valindirect[valindex[j]]];
  194.     }
  195.     public void swap(int i, int j) {
  196.       int tmp = valindex[i];
  197.       valindex[i] = valindex[j];
  198.       valindex[j] = tmp;
  199.     }
  200.     public int[] getSorted() {
  201.       int[] ret = new int[values.length];
  202.       for (int i = 0; i < ret.length; ++i) {
  203.         ret[i] = values[valindirect[valindex[i]]];
  204.       }
  205.       return ret;
  206.     }
  207.     public int[] getValues() {
  208.       int[] ret = new int[values.length];
  209.       System.arraycopy(values, 0, ret, 0, values.length);
  210.       return ret;
  211.     }
  212.   }
  213.   public static class MeasuredSortable implements IndexedSortable {
  214.     private int comparisions;
  215.     private int swaps;
  216.     private final int maxcmp;
  217.     private final int maxswp;
  218.     private IndexedSortable s;
  219.     public MeasuredSortable(IndexedSortable s) {
  220.       this(s, Integer.MAX_VALUE);
  221.     }
  222.     public MeasuredSortable(IndexedSortable s, int maxcmp) {
  223.       this(s, maxcmp, Integer.MAX_VALUE);
  224.     }
  225.     public MeasuredSortable(IndexedSortable s, int maxcmp, int maxswp) {
  226.       this.s = s;
  227.       this.maxcmp = maxcmp;
  228.       this.maxswp = maxswp;
  229.     }
  230.     public int getCmp() { return comparisions; }
  231.     public int getSwp() { return swaps; }
  232.     public int compare(int i, int j) {
  233.       assertTrue("Expected fewer than " + maxcmp + " comparisons",
  234.                  ++comparisions < maxcmp);
  235.       return s.compare(i, j);
  236.     }
  237.     public void swap(int i, int j) {
  238.       assertTrue("Expected fewer than " + maxswp + " swaps",
  239.                  ++swaps < maxswp);
  240.       s.swap(i, j);
  241.     }
  242.   }
  243.   private static class WritableSortable implements IndexedSortable {
  244.     private static Random r = new Random();
  245.     private final int eob;
  246.     private final int[] indices;
  247.     private final int[] offsets;
  248.     private final byte[] bytes;
  249.     private final WritableComparator comparator;
  250.     private final String[] check;
  251.     private final long seed;
  252.     public WritableSortable() throws IOException {
  253.       this(100);
  254.     }
  255.     public WritableSortable(int j) throws IOException {
  256.       seed = r.nextLong();
  257.       r.setSeed(seed);
  258.       Text t = new Text();
  259.       StringBuffer sb = new StringBuffer();
  260.       indices = new int[j];
  261.       offsets = new int[j];
  262.       check = new String[j];
  263.       DataOutputBuffer dob = new DataOutputBuffer();
  264.       for (int i = 0; i < j; ++i) {
  265.         indices[i] = i;
  266.         offsets[i] = dob.getLength();
  267.         genRandom(t, r.nextInt(15) + 1, sb);
  268.         t.write(dob);
  269.         check[i] = t.toString();
  270.       }
  271.       eob = dob.getLength();
  272.       bytes = dob.getData();
  273.       comparator = WritableComparator.get(Text.class);
  274.     }
  275.     public long getSeed() {
  276.       return seed;
  277.     }
  278.     private static void genRandom(Text t, int len, StringBuffer sb) {
  279.       sb.setLength(0);
  280.       for (int i = 0; i < len; ++i) {
  281.         sb.append(Integer.toString(r.nextInt(26) + 10, 36));
  282.       }
  283.       t.set(sb.toString());
  284.     }
  285.     public int compare(int i, int j) {
  286.       final int ii = indices[i];
  287.       final int ij = indices[j];
  288.       return comparator.compare(bytes, offsets[ii],
  289.         ((ii + 1 == indices.length) ? eob : offsets[ii + 1]) - offsets[ii],
  290.         bytes, offsets[ij],
  291.         ((ij + 1 == indices.length) ? eob : offsets[ij + 1]) - offsets[ij]);
  292.     }
  293.     public void swap(int i, int j) {
  294.       int tmp = indices[i];
  295.       indices[i] = indices[j];
  296.       indices[j] = tmp;
  297.     }
  298.     public String[] getValues() {
  299.       return check;
  300.     }
  301.     public String[] getSorted() throws IOException {
  302.       String[] ret = new String[indices.length];
  303.       Text t = new Text();
  304.       DataInputBuffer dib = new DataInputBuffer();
  305.       for (int i = 0; i < ret.length; ++i) {
  306.         int ii = indices[i];
  307.         dib.reset(bytes, offsets[ii],
  308.         ((ii + 1 == indices.length) ? eob : offsets[ii + 1]) - offsets[ii]);
  309.         t.readFields(dib);
  310.         ret[i] = t.toString();
  311.       }
  312.       return ret;
  313.     }
  314.   }
  315. }