private void processKeyValuePairs(Object key, Object value) throws HiveException { String filePath = ""; try { OrcFileValueWrapper v; OrcFileKeyWrapper k; if (key instanceof CombineHiveKey) { k = (OrcFileKeyWrapper) ((CombineHiveKey) key).getKey(); } else { k = (OrcFileKeyWrapper) key; } // skip incompatible file, files that are missing stripe statistics are set to incompatible if (k.isIncompatFile()) { LOG.warn("Incompatible ORC file merge! Stripe statistics is missing. " + k.getInputPath()); incompatFileSet.add(k.getInputPath()); return; } filePath = k.getInputPath().toUri().getPath(); fixTmpPath(k.getInputPath().getParent()); v = (OrcFileValueWrapper) value; if (prevPath == null) { prevPath = k.getInputPath(); reader = OrcFile.createReader(fs, k.getInputPath()); if (isLogInfoEnabled) { LOG.info("ORC merge file input path: " + k.getInputPath()); } } // store the orc configuration from the first file. All other files should // match this configuration before merging else will not be merged if (outWriter == null) { compression = k.getCompression(); compressBuffSize = k.getCompressBufferSize(); version = k.getVersion(); columnCount = k.getTypes().get(0).getSubtypesCount(); rowIndexStride = k.getRowIndexStride(); OrcFile.WriterOptions options = OrcFile.writerOptions(jc) .compress(compression) .version(version) .rowIndexStride(rowIndexStride) .inspector(reader.getObjectInspector()); // compression buffer size should only be set if compression is enabled if (compression != CompressionKind.NONE) { // enforce is required to retain the buffer sizes of old files instead of orc writer // inferring the optimal buffer size options.bufferSize(compressBuffSize).enforceBufferSize(); } outWriter = OrcFile.createWriter(outPath, options); if (isLogDebugEnabled) { LOG.info("ORC merge file output path: " + outPath); } } if (!checkCompatibility(k)) { incompatFileSet.add(k.getInputPath()); return; } // next file in the path if (!k.getInputPath().equals(prevPath)) { reader = OrcFile.createReader(fs, k.getInputPath()); } // initialize buffer to read the entire stripe byte[] buffer = new byte[(int) v.getStripeInformation().getLength()]; fdis = fs.open(k.getInputPath()); fdis.readFully( v.getStripeInformation().getOffset(), buffer, 0, (int) v.getStripeInformation().getLength()); // append the stripe buffer to the new ORC file outWriter.appendStripe( buffer, 0, buffer.length, v.getStripeInformation(), v.getStripeStatistics()); if (isLogInfoEnabled) { LOG.info( "Merged stripe from file " + k.getInputPath() + " [ offset : " + v.getStripeInformation().getOffset() + " length: " + v.getStripeInformation().getLength() + " row: " + v.getStripeStatistics().getColStats(0).getNumberOfValues() + " ]"); } // add user metadata to footer in case of any if (v.isLastStripeInFile()) { outWriter.appendUserMetadata(v.getUserMetadata()); } } catch (Throwable e) { this.exception = true; LOG.error("Closing operator..Exception: " + ExceptionUtils.getStackTrace(e)); throw new HiveException(e); } finally { if (exception) { closeOp(true); } if (fdis != null) { try { fdis.close(); } catch (IOException e) { throw new HiveException(String.format("Unable to close file %s", filePath), e); } finally { fdis = null; } } } }