/** * TODO: chunkNumericPK definition. * * @param table * @param columns * @param chunkSize * @throws ReplicatorException * @throws InterruptedException */ private void chunkNumericPK(Table table, String[] columns, long chunkSize) throws ReplicatorException, InterruptedException { // Retrieve PK range MinMax minmax = retrieveMinMaxCountPK(connection, table); if (minmax != null) { if (logger.isDebugEnabled()) logger.debug( "Min = " + minmax.getMin() + " -- Max = " + minmax.getMax() + " -- Count = " + minmax.getCount()); if (minmax.getCount() <= chunkSize) // Get the whole table at once chunks.put(new NumericChunk(table, columns)); else { // Share the joy among threads, // if primary key is evenly distributed if (!minmax.isDecimal()) { long gap = (Long) minmax.getMax() - (Long) minmax.getMin(); long blockSize = chunkSize * gap / minmax.getCount(); long nbBlocks = gap / blockSize; if (gap % blockSize > 0) nbBlocks++; long start = (Long) minmax.getMin() - 1; long end; do { end = start + blockSize; if (end > (Long) minmax.getMax()) end = (Long) minmax.getMax(); NumericChunk e = new NumericChunk(table, start, end, columns, nbBlocks); chunks.put(e); start = end; } while (start < (Long) minmax.getMax()); } else { BigInteger start = ((BigDecimal) minmax.getMin()) .setScale(0, RoundingMode.FLOOR) .toBigInteger() .subtract(BigInteger.valueOf(1)); BigInteger max = ((BigDecimal) minmax.getMax()).setScale(0, RoundingMode.CEILING).toBigInteger(); BigInteger gap = max.subtract(start); BigInteger blockSize = gap.multiply(BigInteger.valueOf(chunkSize)) .divide(BigInteger.valueOf(minmax.getCount())); long nbBlocks = gap.divide(blockSize).longValue(); if (!gap.remainder(blockSize).equals(BigInteger.ZERO)) { nbBlocks++; blockSize = gap.divide(BigInteger.valueOf(nbBlocks)) .add( gap.remainder(blockSize).equals(BigInteger.ZERO) ? BigInteger.ZERO : BigInteger.ONE); } BigInteger end; do { end = start.add(blockSize); if (end.compareTo( (((BigDecimal) minmax.getMax()).setScale(0, RoundingMode.CEILING)) .toBigInteger()) == 1) end = (((BigDecimal) minmax.getMax()).setScale(0, RoundingMode.CEILING)).toBigInteger(); NumericChunk e = new NumericChunk(table, start, end, columns, nbBlocks); chunks.put(e); start = end; } while (start.compareTo( (((BigDecimal) minmax.getMax()).setScale(0, RoundingMode.CEILING)).toBigInteger()) == -1); } } } else { // table is empty or does not have a // good candidate as a PK for chunking. // Fall back to limit method chunks.put(new NumericChunk(table, columns)); } }
private double calcRowPosition(MinMax minMaxY, DormerRow dormerRow, int dormerRowNum) { double row = (dormerRow.getRowNum() - 1) / (double) dormerRowNum; return minMaxY.getMin() + (minMaxY.getMax() - minMaxY.getMin()) * row; }