diff --git a/java/c/src/main/java/org/apache/arrow/c/CDataReferenceManager.java b/java/c/src/main/java/org/apache/arrow/c/CDataReferenceManager.java index c5c2f977900..84f8f3dc6c5 100644 --- a/java/c/src/main/java/org/apache/arrow/c/CDataReferenceManager.java +++ b/java/c/src/main/java/org/apache/arrow/c/CDataReferenceManager.java @@ -104,7 +104,21 @@ public ArrowBuf deriveBuffer(ArrowBuf sourceBuffer, long index, long length) { @Override public OwnershipTransferResult transferOwnership(ArrowBuf sourceBuffer, BufferAllocator targetAllocator) { - throw new UnsupportedOperationException(); + ArrowBuf targetArrowBuf = this.deriveBuffer(sourceBuffer, 0, sourceBuffer.capacity()); + targetArrowBuf.readerIndex(sourceBuffer.readerIndex()); + targetArrowBuf.writerIndex(sourceBuffer.writerIndex()); + + return new OwnershipTransferResult() { + @Override + public boolean getAllocationFit() { + return true; + } + + @Override + public ArrowBuf getTransferredBuffer() { + return targetArrowBuf; + } + }; } @Override diff --git a/java/c/src/test/java/org/apache/arrow/c/RoundtripTest.java b/java/c/src/test/java/org/apache/arrow/c/RoundtripTest.java index 059ca328453..771397b36dd 100644 --- a/java/c/src/test/java/org/apache/arrow/c/RoundtripTest.java +++ b/java/c/src/test/java/org/apache/arrow/c/RoundtripTest.java @@ -99,6 +99,7 @@ import org.apache.arrow.vector.types.pojo.Field; import org.apache.arrow.vector.types.pojo.FieldType; import org.apache.arrow.vector.types.pojo.Schema; +import org.apache.arrow.vector.util.TransferPair; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -704,6 +705,37 @@ public void testImportReleasedArray() { } } + @Test + public void testTransferImportedBuffer() { + VectorSchemaRoot imported; + + // Consumer allocates empty structures + try (ArrowSchema consumerArrowSchema = ArrowSchema.allocateNew(allocator); + ArrowArray consumerArrowArray = ArrowArray.allocateNew(allocator)) { + try (VectorSchemaRoot vsr = createTestVSR()) { + // Producer creates structures from existing memory pointers + try (ArrowSchema arrowSchema = ArrowSchema.wrap(consumerArrowSchema.memoryAddress()); + ArrowArray arrowArray = ArrowArray.wrap(consumerArrowArray.memoryAddress())) { + // Producer exports vector into the C Data Interface structures + Data.exportVectorSchemaRoot(allocator, vsr, null, arrowArray, arrowSchema); + } + } + // Consumer imports vector + imported = Data.importVectorSchemaRoot(allocator, consumerArrowArray, consumerArrowSchema, null); + } + + try (BufferAllocator targetAllocator = allocator.newChildAllocator("transfer allocator", 0, Long.MAX_VALUE)) { + for (FieldVector fieldVector : imported.getFieldVectors()) { + int cnt = fieldVector.getValueCount(); + // Transfer buffer ownerships. Should not report any error + TransferPair transferPair = fieldVector.getTransferPair(targetAllocator); + transferPair.transfer(); + ValueVector to = transferPair.getTo(); + assertEquals(cnt, to.getValueCount()); + } + } + } + private VectorSchemaRoot createTestVSR() { BitVector bitVector = new BitVector("boolean", allocator);