1 30 31 32 package org.hsqldb.lib; 33 34 42 public class ArrayCounter { 43 44 58 public static int[] countSegments(int[] array, int elements, 59 int segments, int start, int limit) { 60 61 int[] counts = new int[segments]; 62 long interval = calcInterval(segments, start, limit); 63 int index = 0; 64 int element = 0; 65 66 if (interval <= 0) { 67 return counts; 68 } 69 70 for (int i = 0; i < elements; i++) { 71 element = array[i]; 72 73 if (element < start || element >= limit) { 74 continue; 75 } 76 77 index = (int) ((element - start) / interval); 78 79 counts[index]++; 80 } 81 82 return counts; 83 } 84 85 101 public static int rank(int[] array, int elements, int target, int start, 102 int limit, int margin) { 103 104 final int segments = 256; 105 int elementCount = 0; 106 int currentLimit = limit; 107 108 for (;;) { 109 long interval = calcInterval(segments, start, currentLimit); 110 int[] counts = countSegments(array, elements, segments, start, 111 currentLimit); 112 113 for (int i = 0; i < counts.length; i++) { 114 if (elementCount + counts[i] < target) { 115 elementCount += counts[i]; 116 start += interval; 117 } else { 118 break; 119 } 120 } 121 122 if (elementCount + margin >= target) { 123 return start; 124 } 125 126 if (interval <= 1) { 127 return start; 128 } 129 130 currentLimit = start + interval < limit ? (int) (start + interval) 131 : limit; 132 } 133 } 134 135 140 static long calcInterval(int segments, int start, int limit) { 141 142 long range = limit - start; 143 144 if (range < 0) { 145 return 0; 146 } 147 148 int partSegment = (range % segments) == 0 ? 0 149 : 1; 150 151 return (range / segments) + partSegment; 152 } 153 } 154 | Popular Tags |