Skip to content

Commit

Permalink
Merge branch 'release/0.2.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
xerial committed Dec 11, 2013
2 parents c7f6f67 + 0ca48eb commit dc81351
Show file tree
Hide file tree
Showing 17 changed files with 332 additions and 130 deletions.
17 changes: 9 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
LArray
===
A library for managing large off-heap arrays that can hold more than 2G (2^31) entries in Java and Scala.
A library for managing large off-heap arrays that can hold more than 2G (2^31) entries in Java and Scala. Notably LArray is *disposable* by calling `LArray.free` or you can let GC automatically release the memory. LArray also can be used to create an `mmap` (memory-mapped file) whose size is more than 2GB.

## Features
* LArray can create arrays with more than 2G(2^31) entries.
Expand Down Expand Up @@ -94,6 +94,7 @@ A standard JVM, (e.g. Oracle JVM (standard JVM, HotSpotVM) or OpenJDK) must be u


## History
* November 11, 2013 version 0.2.1 - Use orgnization name `org.xerial.larray`. Add LBuffer.view.
* November 11, 2013 version 0.2 - Extracted pure-java modules (larray-buffer.jar and larray-mmap.jar) from larray.jar (for Scala).
* August 28, 2013 version 0.1.2 - improved memory layout
* August 28, 2013 version 0.1.1 (for Scala 2.10.2)
Expand All @@ -105,15 +106,15 @@ A standard JVM, (e.g. Oracle JVM (standard JVM, HotSpotVM) or OpenJDK) must be u
Add the following sbt dependency to your project settings:

```scala
libraryDependencies += "org.xerial" % "larray" % "0.2"
libraryDependencies += "org.xerial.larray" % "larray" % "0.2.1"
```

* Using snapshot versions:

```scala
resolvers += "Sonatype shapshot repo" at "https://oss.sonatype.org/content/repositories/snapshots/"

libraryDependencies += "org.xerial" % "larray" % "0.2-SNAPSHOT"
libraryDependencies += "org.xerial.larray" % "larray" % "0.2.2-SNAPSHOT"
```
### Example

Expand All @@ -137,16 +138,16 @@ l2.free
l2(0) // The result of accessing released LArray is undefined
```

For more examples, see [xerial/larray/example/LArrayExample.scala](larray-scala/src/main/scala/xerial/larray/example/LArrayExample.scala)
For more examples, see [xerial/larray/example/LArrayExample.scala](larray/src/main/scala/xerial/larray/example/LArrayExample.scala)

## Usage (Java)

Add the following dependency to your pom.xml (Maven):
```xml
<dependency>
<groupId>org.xerial</groupId>
<groupId>org.xerial.larray</groupId>
<artifactId>larray</artifactId>
<version>0.2</version>
<version>0.2.1</version>
</dependency>
```

Expand All @@ -165,11 +166,11 @@ int e0 = l.apply(0L); // Get l[0L]
// release
l.free();
```
For more examples, see [xerial/larray/example/LArrayJavaExample.scala](larray-scala/src/main/scala/xerial/larray/example/LArrayJavaExample.java)
For more examples, see [xerial/larray/example/LArrayJavaExample.scala](larray/src/main/scala/xerial/larray/example/LArrayJavaExample.java)

## Scaladoc

* [LArray Scala API](https://oss.sonatype.org/service/local/repositories/releases/archive/org/xerial/larray/0.2/larray-0.2-javadoc.jar/!/index.html#xerial.larray.package)
* [LArray Scala API](https://oss.sonatype.org/service/local/repositories/releases/archive/org/xerial/larray/larray/0.2.1/larray-0.2.1-javadoc.jar/!/index.html#xerial.larray.package)

## For developers

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,112 +1,33 @@
package xerial.larray.buffer;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.xerial.util.log.Logger;

import java.lang.ref.ReferenceQueue;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

import static xerial.larray.buffer.UnsafeUtil.unsafe;


/**
* Stores |(memory size:long)| data ... |
*/
class OffHeapMemory implements Memory {

private final long _data;

public static long HEADER_SIZE = 8L;

/**
* Create an empty memory
*/
public OffHeapMemory() {
this._data = 0L;
}

public OffHeapMemory(long address) {
if(address != 0L)
this._data = address + HEADER_SIZE;
else
this._data = 0L;
}

public OffHeapMemory(long address, long size) {
if(address != 0L) {
this._data = address + HEADER_SIZE;
unsafe.putLong(address, size);
}
else {
this._data = 0L;
}
}

public long headerAddress() {
return _data - HEADER_SIZE;
}
public long size() {
return (_data == 0) ? 0L : unsafe.getLong(headerAddress()) + HEADER_SIZE;
}

public long address() {
return _data;
}

public long dataSize() {
return (_data == 0) ? 0L : unsafe.getLong(headerAddress());
}

public MemoryReference toRef(ReferenceQueue<Memory> queue) {
return new OffHeapMemoryReference(this, queue);
}

public void release() {
if(_data != 0)
UnsafeUtil.unsafe.freeMemory(headerAddress());
}
}

class OffHeapMemoryReference extends MemoryReference {

/**
* Create a phantom reference
* @param m the allocated memory
* @param queue the reference queue to which GCed reference of the Memory will be inserted
*/
public OffHeapMemoryReference(Memory m, ReferenceQueue<Memory> queue) {
super(m, queue);
}

public Memory toMemory() {
if(address != 0)
return new OffHeapMemory(address);
else
return new OffHeapMemory();
}

public String name() { return "off-heap"; }

}



/**
* Allocating off-heap memory
* A default implementation of MemoryAllocator that allocates off-heap memory and releases allocated memories in a background thread.
*
* @author Taro L. Saito
*/
public class OffHeapMemoryAllocator implements MemoryAllocator {
public class DefaultMemoryAllocator implements MemoryAllocator {

private Logger logger = Logger.getLogger(DefaultMemoryAllocator.class);

private Logger logger = LoggerFactory.getLogger(OffHeapMemoryAllocator.class);

// Table from address -> MemoryReference
private Map<Long, MemoryReference> allocatedMemoryReferences = new ConcurrentHashMap<Long, MemoryReference>();
private ReferenceQueue<Memory> queue = new ReferenceQueue<Memory>();

{
// Enable ANSI Color
logger.enableColor(true);

// Start OffHeapMemory collector that releases the allocated memory when the corresponding Memory object is collected by GC.
Thread collector = new Thread(new Runnable() {
@Override
Expand Down Expand Up @@ -136,15 +57,19 @@ public void run() {
*/
public long allocatedSize() { return totalAllocatedSize.get(); }

/**
* Allocate a memory of the specified byte length. The allocated memory must be released via `release`
* as in malloc() in C/C++.
* @param size byte length of the memory
* @return allocated memory information
*/
public Memory allocate(long size) {
if(size == 0L)
return new OffHeapMemory();
return new OffHeapMemory();

// Allocate memory of the given size + HEADER space
long memorySize = size + OffHeapMemory.HEADER_SIZE;
long address = unsafe.allocateMemory(memorySize);
if(logger.isTraceEnabled())
logger.trace(String.format("Allocated memory address:%x, size:%,d", address, size));
long address = UnsafeUtil.unsafe.allocateMemory(memorySize);
Memory m = new OffHeapMemory(address, size);
register(m);
return m;
Expand Down Expand Up @@ -183,10 +108,9 @@ public void release(Memory m) {
synchronized(this) {
long address = m.headerAddress();
if(allocatedMemoryReferences.containsKey(address)) {
long size = m.size();
if(logger.isTraceEnabled())
logger.trace(String.format("Released memory address:%x, size:%,d", address, size));
totalAllocatedSize.getAndAdd(-size);
logger.trace(String.format("Released memory address:%x, size:%,d", address, m.dataSize()));
totalAllocatedSize.getAndAdd(-m.size());
allocatedMemoryReferences.remove(address);
m.release();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class LBuffer extends LBufferAPI {
* @param size byte size of the array
*/
public LBuffer(long size) {
super(BufferConfig.allocator.allocate(size));
super(LBufferConfig.allocator.allocate(size));
}


Expand Down
Loading

0 comments on commit dc81351

Please sign in to comment.