AlgART Home
net.algart.arrays

Interface DataBuffer

Specific subinterfaces

The data() method, declared in this interface, returns Object (the only existing superclass for all Java arrays), that is not too convenient. But there are subinterfaces DataBitBuffer, DataCharBuffer, DataByteBuffer, DataShortBuffer, DataIntBuffer, DataLongBuffer, DataFloatBuffer, DataDoubleBuffer, DataObjectBuffer, where this method is overridden and returns corresponding type of Java array: long[] (packed bit array), char[], byte[], short[], etc. The basic Array.buffer(net.algart.arrays.DataBuffer.AccessMode, long) method (as well as its overloaded simplified versions) is overridden in specific AlgART arrays (BitArray, CharArray, etc.) and returns one of the listed subinterfaces.

Sequential mapping all AlgART array

This interface has no methods allowing to get the reference to the underlying AlgART array or get its length. But you may check, whether all elements of the AlgART array were already mapped by sequential calls of mapNext() method, by hasData() method (which is equivalent to "count()>0" check). If mapNext() is called when mapping position + count() = length, then new mapping position becomes equal to length and, so, the buffer size count() becomes zero. But please remember that hasData() returns false also before the first mapping of a newly created data buffer.

Usage examples

Below is a typical usage example:

 ByteArray a = ...; // some byte AlgART array
 for (DataByteBuffer buf = a.buffer().map(0); buf.hasData(); buf.mapNext()) {
     byte[] data = buf.data();
     for (int k = buf.from(); k < buf.to(); k++) {
         // ... (analyzing and/or replacing data[k])
     }
     buf.force(); // necessary only if data were modified
 }
 

There is an equivalent form of this loop, little more complex, but easily generalized for the case of another accessing order:

 ByteArray a = ...; // some byte AlgART array
 DataByteBuffer buf = a.buffer();
 for (long p = 0, n = a.length(); p < n; p += buf.count()) {
     buf.map(p);
     byte[] data = buf.data();
     for (int k = buf.from(); k < buf.to(); k++) {
         // ... (analyzing and/or replacing data[k])
     }
     buf.force(); // necessary only if data were modified
 }
 

A usage example for bits:

 BitArray a = ...; // some bit AlgART array
 for (DataBitBuffer buf = a.buffer().map(0); buf.hasData(); buf.mapNext()) {
     long[] data = buf.data();
     for (long k = buf.fromIndex(); k < buf.toIndex(); k++) {
         boolean b = PackedBitArrays.getBit(data, k);
         // it is the element a.getBit(position()+k)
         // processing this bit...
         // then, if necessary:
         PackedBitArrays.setBit(data, k, someNewValue);
     }
     buf.force(); // necessary only if data were modified
 }
 

Performance problem connected with a lot of data buffers

There is a problem connected with creating and using a lot of indirect data buffers (thousands and tens of thousands). In this situation, every data buffer allocates its own Java array for storing data, that cannot be shared with other data buffers. Allocating thousands of Java array, where every array occupies tens of kilobytes or more (typical capacity for data buffers), may require much time and create great workload for the garbage collector. As a result, it may lead to reducing overall performance. (Of course, the direct buffers do not lead to such a problem.)

The same problem occurs with usual Java arrays, used for temporary buffers instead of this class. But JArrayPool class offers a solution for this problem for Java arrays. So, if allocation of the data buffer may really create the described performance problem, you should check the newly created buffer, is it direct, and, if not, ignore it and use standard Java arrays with help of JArrayPool.

Additional notes

The data buffers are allowed not to implement hashCode and equals method. Usually, the default implementation of these methods from Object class are used.

The data buffers are not thread-safe, but are thread-compatible and can be synchronized manually (together with AlgART arrays accessed via the buffers) if multithread access is necessary.

AlgART Laboratory 2007–2014

Since:
JDK 1.5
Version:
1.2
Author:
Daniel Alievsky