Commit 4d3db992 authored by pjulien's avatar pjulien Committed by Wouter van Oortmerssen

Issue #136

The satellite data of the ``ByteBuffer`` cannot be modified in
any way and stay thread safe in the presence of concurrent readers.

This implementation is simple and does introduce an allocation, however
without it multiple readers will quickly and continuously encounter
``IndexOutOfBoundsException`` exceptions.

An alternative, but possibly more controversial, implementation would
be to use ``Unsafe``.  Using ``Unsafe``, it's possible to do an
array copy with a provided buffer index.

Change-Id: I851d4034e753b3be2931ee2249ec2c82dde43135
parent 72b9501e
...@@ -18,6 +18,7 @@ package com.google.flatbuffers; ...@@ -18,6 +18,7 @@ package com.google.flatbuffers;
import static com.google.flatbuffers.Constants.*; import static com.google.flatbuffers.Constants.*;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.ByteOrder;
// All tables in the generated code derive from this class, and add their own accessors. // All tables in the generated code derive from this class, and add their own accessors.
public class Table { public class Table {
...@@ -46,13 +47,13 @@ public class Table { ...@@ -46,13 +47,13 @@ public class Table {
if (bb.hasArray()) { if (bb.hasArray()) {
return new String(bb.array(), offset + SIZEOF_INT, bb.getInt(offset), FlatBufferBuilder.utf8charset); return new String(bb.array(), offset + SIZEOF_INT, bb.getInt(offset), FlatBufferBuilder.utf8charset);
} else { } else {
// We can't access .array(), since the ByteBuffer is read-only. // We can't access .array(), since the ByteBuffer is read-only,
// off-heap or a memory map
ByteBuffer bb = this.bb.duplicate().order(ByteOrder.LITTLE_ENDIAN);
// We're forced to make an extra copy: // We're forced to make an extra copy:
byte[] copy = new byte[bb.getInt(offset)]; byte[] copy = new byte[bb.getInt(offset)];
int old_pos = bb.position();
bb.position(offset + SIZEOF_INT); bb.position(offset + SIZEOF_INT);
bb.get(copy); bb.get(copy);
bb.position(old_pos);
return new String(copy, 0, copy.length, FlatBufferBuilder.utf8charset); return new String(copy, 0, copy.length, FlatBufferBuilder.utf8charset);
} }
} }
...@@ -77,12 +78,11 @@ public class Table { ...@@ -77,12 +78,11 @@ public class Table {
protected ByteBuffer __vector_as_bytebuffer(int vector_offset, int elem_size) { protected ByteBuffer __vector_as_bytebuffer(int vector_offset, int elem_size) {
int o = __offset(vector_offset); int o = __offset(vector_offset);
if (o == 0) return null; if (o == 0) return null;
int old_pos = bb.position(); ByteBuffer bb = this.bb.duplicate().order(ByteOrder.LITTLE_ENDIAN);
bb.position(__vector(o)); int vectorstart = __vector(o);
ByteBuffer nbb = bb.slice(); bb.position(vectorstart);
bb.position(old_pos); bb.limit(vectorstart + __vector_len(o) * elem_size);
nbb.limit(__vector_len(o) * elem_size); return bb;
return nbb;
} }
// Initialize any Table-derived type to point to the union at the given offset. // Initialize any Table-derived type to point to the union at the given offset.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment