Author: bperroud
Date: Fri Jan 6 13:41:13 2012
New Revision: 1228174
URL: http://svn.apache.org/viewvc?rev=1228174&view=rev
Log:
DIRECTMEMORY-53 : MemoryMamagerService buffers allocation policy
Added:
incubator/directmemory/trunk/directmemory-cache/src/main/java/org/apache/directmemory/memory/AllocationPolicy.java
incubator/directmemory/trunk/directmemory-cache/src/main/java/org/apache/directmemory/memory/MemoryManagerServiceWithAllocationPolicyImpl.java
incubator/directmemory/trunk/directmemory-cache/src/main/java/org/apache/directmemory/memory/RoundRobinAllocationPolicy.java
incubator/directmemory/trunk/directmemory-cache/src/test/java/org/apache/directmemory/memory/test/MemoryManagerServiceImplWithMerginOHMBAndAllocationPolicyTest.java
incubator/directmemory/trunk/directmemory-cache/src/test/java/org/apache/directmemory/memory/test/RoundRobinAllocationPolicyTest.java
Modified:
incubator/directmemory/trunk/directmemory-cache/src/main/java/org/apache/directmemory/memory/MemoryManagerServiceImpl.java
Added:
incubator/directmemory/trunk/directmemory-cache/src/main/java/org/apache/directmemory/memory/AllocationPolicy.java
URL:
http://svn.apache.org/viewvc/incubator/directmemory/trunk/directmemory-cache/src/main/java/org/apache/directmemory/memory/AllocationPolicy.java?rev=1228174&view=auto
==============================================================================
---
incubator/directmemory/trunk/directmemory-cache/src/main/java/org/apache/directmemory/memory/AllocationPolicy.java
(added)
+++
incubator/directmemory/trunk/directmemory-cache/src/main/java/org/apache/directmemory/memory/AllocationPolicy.java
Fri Jan 6 13:41:13 2012
@@ -0,0 +1,57 @@
+package org.apache.directmemory.memory;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+/**
+ * Interface describing the buffer allocation policy.
+ * The implementations will be initialized by setting the list of buffers
{@link #setBuffers(List)},
+ * and every allocation will call {@link #getActiveBuffer(OffHeapMemoryBuffer,
int)},
+ * passing the previously (possibly null) buffer that failed to allocate and
the number of the current allocation
+ *
+ * @author bperroud
+ *
+ */
+public interface AllocationPolicy
+{
+
+ /**
+ * Initialization function.
+ *
+ * @param buffers
+ */
+ void setBuffers( List<OffHeapMemoryBuffer> buffers );
+
+ /**
+ * Returns the active buffer in which to allocate.
+ *
+ * @param previouslyAllocatedBuffer : the previously allocated buffer, or
null if it's the first allocation
+ * @param allocationNumber : the number of time the allocation has already
failed.
+ * @return the buffer to allocate, or null if allocation has failed.
+ */
+ OffHeapMemoryBuffer getActiveBuffer( OffHeapMemoryBuffer
previouslyAllocatedBuffer, int allocationNumber );
+
+ /**
+ * Reset internal state
+ */
+ void reset();
+
+}
Modified:
incubator/directmemory/trunk/directmemory-cache/src/main/java/org/apache/directmemory/memory/MemoryManagerServiceImpl.java
URL:
http://svn.apache.org/viewvc/incubator/directmemory/trunk/directmemory-cache/src/main/java/org/apache/directmemory/memory/MemoryManagerServiceImpl.java?rev=1228174&r1=1228173&r2=1228174&view=diff
==============================================================================
---
incubator/directmemory/trunk/directmemory-cache/src/main/java/org/apache/directmemory/memory/MemoryManagerServiceImpl.java
(original)
+++
incubator/directmemory/trunk/directmemory-cache/src/main/java/org/apache/directmemory/memory/MemoryManagerServiceImpl.java
Fri Jan 6 13:41:13 2012
@@ -32,9 +32,9 @@ public class MemoryManagerServiceImpl
protected static Logger logger = LoggerFactory.getLogger(
MemoryManager.class );
- private List<OffHeapMemoryBuffer> buffers = new
ArrayList<OffHeapMemoryBuffer>();
+ protected List<OffHeapMemoryBuffer> buffers = new
ArrayList<OffHeapMemoryBuffer>();
- private int activeBufferIndex = 0;
+ protected int activeBufferIndex = 0;
public MemoryManagerServiceImpl()
{
Added:
incubator/directmemory/trunk/directmemory-cache/src/main/java/org/apache/directmemory/memory/MemoryManagerServiceWithAllocationPolicyImpl.java
URL:
http://svn.apache.org/viewvc/incubator/directmemory/trunk/directmemory-cache/src/main/java/org/apache/directmemory/memory/MemoryManagerServiceWithAllocationPolicyImpl.java?rev=1228174&view=auto
==============================================================================
---
incubator/directmemory/trunk/directmemory-cache/src/main/java/org/apache/directmemory/memory/MemoryManagerServiceWithAllocationPolicyImpl.java
(added)
+++
incubator/directmemory/trunk/directmemory-cache/src/main/java/org/apache/directmemory/memory/MemoryManagerServiceWithAllocationPolicyImpl.java
Fri Jan 6 13:41:13 2012
@@ -0,0 +1,93 @@
+package org.apache.directmemory.memory;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * PoC of {@link MemoryManagerService} that allows {@link AllocationPolicy} to
get wired.
+ *
+ * @author bperroud
+ *
+ */
+public class MemoryManagerServiceWithAllocationPolicyImpl
+ extends MemoryManagerServiceImpl
+{
+
+ protected AllocationPolicy allocationPolicy;
+
+ @Override
+ public void init( int numberOfBuffers, int size )
+ {
+ super.init( numberOfBuffers, size );
+ allocationPolicy.setBuffers( getBuffers() );
+ }
+
+ public void setAllocationPolicy( final AllocationPolicy allocationPolicy )
+ {
+ this.allocationPolicy = allocationPolicy;
+ }
+
+ @Override
+ public OffHeapMemoryBuffer getActiveBuffer() {
+ return allocationPolicy.getActiveBuffer( null, 0 );
+ }
+
+ @Override
+ public Pointer store( byte[] payload, int expiresIn )
+ {
+ Pointer p = null;
+ OffHeapMemoryBuffer buffer = null;
+ int allocationNumber = 1;
+ do {
+ buffer = allocationPolicy.getActiveBuffer( buffer,
allocationNumber );
+ if (buffer == null) {
+ return null;
+ }
+ p = buffer.store( payload, expiresIn );
+ allocationNumber++;
+ } while (p == null);
+ return p;
+ }
+
+ @Override
+ public void clear()
+ {
+ super.clear();
+ allocationPolicy.reset();
+ }
+
+
+ @Override
+ public Pointer allocate( int size, long expiresIn, long expires )
+ {
+ Pointer p = null;
+ OffHeapMemoryBuffer buffer = null;
+ int allocationNumber = 1;
+ do {
+ buffer = allocationPolicy.getActiveBuffer( buffer,
allocationNumber );
+ if (buffer == null) {
+ return null;
+ }
+ p = buffer.allocate( size, expiresIn, expires );
+ allocationNumber++;
+ } while (p == null);
+ return p;
+ }
+
+}
Added:
incubator/directmemory/trunk/directmemory-cache/src/main/java/org/apache/directmemory/memory/RoundRobinAllocationPolicy.java
URL:
http://svn.apache.org/viewvc/incubator/directmemory/trunk/directmemory-cache/src/main/java/org/apache/directmemory/memory/RoundRobinAllocationPolicy.java?rev=1228174&view=auto
==============================================================================
---
incubator/directmemory/trunk/directmemory-cache/src/main/java/org/apache/directmemory/memory/RoundRobinAllocationPolicy.java
(added)
+++
incubator/directmemory/trunk/directmemory-cache/src/main/java/org/apache/directmemory/memory/RoundRobinAllocationPolicy.java
Fri Jan 6 13:41:13 2012
@@ -0,0 +1,106 @@
+package org.apache.directmemory.memory;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Round Robin allocation policy.
+ * An internal counter is incremented (modulo the size of the buffer),
+ * so each calls to {@link #getActiveBuffer(OffHeapMemoryBuffer, int)}
+ * will increment the counter and return the buffer at the index of the
counter.
+ *
+ * @author bperroud
+ *
+ */
+public class RoundRobinAllocationPolicy
+ implements AllocationPolicy
+{
+
+ // Increment the counter and get the value. Need to start at -1 to have
0'index at first call.
+ private static final int BUFFERS_INDEX_INITIAL_VALUE = -1;
+
+ // All the buffers to allocate
+ private List<OffHeapMemoryBuffer> buffers;
+
+ // Cyclic counter
+ private AtomicInteger buffersIndexCounter = new AtomicInteger(
BUFFERS_INDEX_INITIAL_VALUE );
+
+ // Default max number of allocations before returning null buffer.
+ private static final int DEFAULT_MAX_ALLOCATIONS = 2;
+
+ // Current max number of allocations
+ private int maxAllocations = DEFAULT_MAX_ALLOCATIONS;
+
+ public void setMaxAllocations( int maxAllocations )
+ {
+ this.maxAllocations = maxAllocations;
+ }
+
+ @Override
+ public void setBuffers( List<OffHeapMemoryBuffer> buffers )
+ {
+ this.buffers = buffers;
+ }
+
+ @Override
+ public OffHeapMemoryBuffer getActiveBuffer( OffHeapMemoryBuffer
previouslyAllocatedBuffer,
+ int
allocationNumber )
+ {
+ // If current allocation is more than the limit, return a null buffer.
+ if ( allocationNumber > maxAllocations )
+ {
+ return null;
+ }
+
+ // Thread safely increment and get the next buffer's index
+ int i = incrementAndGetBufferIndex();
+
+ final OffHeapMemoryBuffer buffer = buffers.get( i );
+
+ return buffer;
+ }
+
+ @Override
+ public void reset()
+ {
+ // Reinitialize the counter to it's initial value
+ buffersIndexCounter.set( BUFFERS_INDEX_INITIAL_VALUE );
+ }
+
+ /**
+ * Optimistic (lock free) cyclic (modulo size of the buffer) increment of
the counter
+ * @return next index
+ */
+ private int incrementAndGetBufferIndex()
+ {
+ int newIndex = 0;
+ boolean updateOk = false;
+ do
+ {
+ int currentIndex = buffersIndexCounter.get();
+ newIndex = ( currentIndex + 1 ) % buffers.size();
+ updateOk = buffersIndexCounter.compareAndSet( currentIndex,
newIndex );
+ }
+ while ( !updateOk );
+ return newIndex;
+ }
+}
Added:
incubator/directmemory/trunk/directmemory-cache/src/test/java/org/apache/directmemory/memory/test/MemoryManagerServiceImplWithMerginOHMBAndAllocationPolicyTest.java
URL:
http://svn.apache.org/viewvc/incubator/directmemory/trunk/directmemory-cache/src/test/java/org/apache/directmemory/memory/test/MemoryManagerServiceImplWithMerginOHMBAndAllocationPolicyTest.java?rev=1228174&view=auto
==============================================================================
---
incubator/directmemory/trunk/directmemory-cache/src/test/java/org/apache/directmemory/memory/test/MemoryManagerServiceImplWithMerginOHMBAndAllocationPolicyTest.java
(added)
+++
incubator/directmemory/trunk/directmemory-cache/src/test/java/org/apache/directmemory/memory/test/MemoryManagerServiceImplWithMerginOHMBAndAllocationPolicyTest.java
Fri Jan 6 13:41:13 2012
@@ -0,0 +1,206 @@
+package org.apache.directmemory.memory.test;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.Assert;
+
+import org.apache.directmemory.memory.MemoryManagerService;
+import
org.apache.directmemory.memory.MemoryManagerServiceWithAllocationPolicyImpl;
+import org.apache.directmemory.memory.OffHeapMemoryBuffer;
+import org.apache.directmemory.memory.OffHeapMergingMemoryBufferImpl;
+import org.apache.directmemory.memory.Pointer;
+import org.apache.directmemory.memory.RoundRobinAllocationPolicy;
+import org.junit.Test;
+
+public class MemoryManagerServiceImplWithMerginOHMBAndAllocationPolicyTest
+ extends MemoryManagerServiceImplTest
+{
+
+ @Override
+ protected MemoryManagerService getMemoryManagerService()
+ {
+ // Initialize MemoryManagerService with OffHeapMergingMemoryBufferImpl
and AllocationPolicy
+ final MemoryManagerServiceWithAllocationPolicyImpl mms = new
MemoryManagerServiceWithAllocationPolicyImpl()
+ {
+ @Override
+ protected OffHeapMemoryBuffer instanciateOffHeapMemoryBuffer( int
size, int bufferNumber )
+ {
+ return OffHeapMergingMemoryBufferImpl.createNew( size,
bufferNumber );
+ }
+ };
+
+ mms.setAllocationPolicy( new RoundRobinAllocationPolicy() );
+ return mms;
+ }
+
+ @Test
+ public void testFullFillAndClearBuffer()
+ {
+
+ final int NUMBER_OF_OBJECTS = 10;
+ final int BUFFER_SIZE = NUMBER_OF_OBJECTS * SMALL_PAYLOAD.length;
+
+ final MemoryManagerService memoryManagerService =
getMemoryManagerService();
+
+ memoryManagerService.init( 1, BUFFER_SIZE );
+
+ Pointer pointerFull = memoryManagerService.store(
MemoryTestUtils.generateRandomPayload( BUFFER_SIZE ) );
+ Assert.assertNotNull( pointerFull );
+ memoryManagerService.free( pointerFull );
+
+ final int size1 = R.nextInt( BUFFER_SIZE / 2 ) + 1;
+ Pointer pointer1 = memoryManagerService.store(
MemoryTestUtils.generateRandomPayload( size1 ) );
+ Assert.assertNotNull( "Cannot store " + size1 + " bytes", pointer1 );
+
+ final int size2 = R.nextInt( ( BUFFER_SIZE - size1 ) / 2 ) + 1;
+ Pointer pointer2 = memoryManagerService.store(
MemoryTestUtils.generateRandomPayload( size2 ) );
+ Assert.assertNotNull( "Cannot store " + size2 + " bytes", pointer2 );
+
+ final int size3 = R.nextInt( ( BUFFER_SIZE - size1 - size2 ) / 2 ) + 1;
+ Pointer pointer3 = memoryManagerService.store(
MemoryTestUtils.generateRandomPayload( size3 ) );
+ Assert.assertNotNull( "Cannot store " + size3 + " bytes", pointer3 );
+
+ final int size4 = BUFFER_SIZE - size1 - size2 - size3;
+ Pointer pointer4 = memoryManagerService.store(
MemoryTestUtils.generateRandomPayload( size4 ) );
+ Assert.assertNotNull( "Cannot store " + size4 + " bytes", pointer4 );
+
+ memoryManagerService.free( pointer1 );
+
+ memoryManagerService.free( pointer3 );
+
+ memoryManagerService.free( pointer4 );
+
+ memoryManagerService.free( pointer2 );
+
+ Assert.assertEquals( 0, memoryManagerService.getBuffers().get( 0
).used() );
+
+ // As all pointers have been freeed, we should be able to reallocate
the
+ // whole buffer
+ Pointer pointer6 = memoryManagerService.store(
MemoryTestUtils.generateRandomPayload( BUFFER_SIZE ) );
+ Assert.assertNotNull( "Cannot store " + BUFFER_SIZE + " bytes",
pointer6 );
+
+ memoryManagerService.clear();
+
+ // As all pointers have been cleared, we should be able to reallocate
+ // the whole buffer
+ Pointer pointer7 = memoryManagerService.store(
MemoryTestUtils.generateRandomPayload( BUFFER_SIZE ) );
+ Assert.assertNotNull( "Cannot store " + BUFFER_SIZE + " bytes",
pointer7 );
+
+ memoryManagerService.clear();
+
+ // As all pointers have been cleared, we should be able to reallocate
+ // the whole buffer
+ for ( int i = 0; i < NUMBER_OF_OBJECTS; i++ )
+ {
+ Pointer pointer = memoryManagerService.store( SMALL_PAYLOAD );
+ Assert.assertNotNull( pointer );
+ }
+
+ memoryManagerService.clear();
+
+ // As all pointers have been cleared, we should be able to reallocate
+ // the whole buffer
+ Pointer pointer8 = memoryManagerService.store(
MemoryTestUtils.generateRandomPayload( BUFFER_SIZE ) );
+ Assert.assertNotNull( "Cannot store " + BUFFER_SIZE + " bytes",
pointer8 );
+
+ memoryManagerService.free( pointer8 );
+
+ // As all pointers have been cleared, we should be able to reallocate
+ // the whole buffer
+ for ( int i = 0; i < NUMBER_OF_OBJECTS * 10; i++ )
+ {
+ Pointer pointer = memoryManagerService.store( SMALL_PAYLOAD );
+ Assert.assertNotNull( pointer );
+ memoryManagerService.free( pointer );
+ }
+
+ }
+
+ @Test
+ public void testStoreAllocAndFree()
+ {
+
+ final int NUMBER_OF_OBJECTS = 100;
+ final int BUFFER_SIZE = NUMBER_OF_OBJECTS * SMALL_PAYLOAD.length;
+
+ final MemoryManagerService memoryManagerService =
getMemoryManagerService();
+
+ memoryManagerService.init( 1, BUFFER_SIZE );
+
+ List<Pointer> pointers = new ArrayList<Pointer>( NUMBER_OF_OBJECTS );
+ for ( int i = 0; i < NUMBER_OF_OBJECTS; i++ )
+ {
+ byte[] payload = MemoryTestUtils.generateRandomPayload(
SMALL_PAYLOAD.length );
+ Pointer pointer = memoryManagerService.store( payload );
+ Assert.assertNotNull( pointer );
+ pointers.add( pointer );
+ byte[] fetchedPayload = memoryManagerService.retrieve( pointer );
+ Assert.assertEquals( new String( payload ), new String(
fetchedPayload ) );
+ }
+
+ // Free 1/4 of the pointers, from 1/4 of the address space to 1/2
+ for ( int i = NUMBER_OF_OBJECTS / 4; i < NUMBER_OF_OBJECTS / 2; i++ )
+ {
+ Pointer pointer = pointers.get( i );
+ memoryManagerService.free( pointer );
+ }
+
+ // Should be able to allocate NUMBER_OF_OBJECTS / 4 *
+ // SMALL_PAYLOAD.length bytes
+ Pointer pointer1 = memoryManagerService.allocate( NUMBER_OF_OBJECTS /
4 * SMALL_PAYLOAD.length, 0, 0 );
+ Assert.assertNotNull( "Cannot store " + ( NUMBER_OF_OBJECTS / 4 *
SMALL_PAYLOAD.length ) + " bytes", pointer1 );
+
+ int pointerToSkip = NUMBER_OF_OBJECTS / 2 + NUMBER_OF_OBJECTS / 10;
+ for ( int i = NUMBER_OF_OBJECTS / 2; i < NUMBER_OF_OBJECTS * 3 / 4;
i++ )
+ {
+ // skip one pointer
+ if ( i == pointerToSkip )
+ {
+ continue;
+ }
+ Pointer pointer = pointers.get( i );
+ memoryManagerService.free( pointer );
+ }
+
+ // Should NOT be able to allocate NUMBER_OF_OBJECTS / 4 *
+ // SMALL_PAYLOAD.length bytes
+ Pointer pointer2 = memoryManagerService.allocate( NUMBER_OF_OBJECTS /
4 * SMALL_PAYLOAD.length, 0, 0 );
+ Assert.assertNull( pointer2 );
+
+ // Freeing the previously skipped pointer should then merge the whole
+ // memory space
+ memoryManagerService.free( pointers.get( pointerToSkip ) );
+
+ // Should be able to allocate NUMBER_OF_OBJECTS / 4 *
+ // SMALL_PAYLOAD.length bytes
+ Pointer pointer3 = memoryManagerService.allocate( NUMBER_OF_OBJECTS /
4 * SMALL_PAYLOAD.length, 0, 0 );
+ Assert.assertNotNull( pointer3 );
+
+ byte[] payload3 = MemoryTestUtils.generateRandomPayload(
NUMBER_OF_OBJECTS / 4 * SMALL_PAYLOAD.length );
+ pointer3.directBuffer.put( payload3 );
+ byte[] retrievePayload3 = memoryManagerService.retrieve( pointer3 );
+ Assert.assertEquals( new String( payload3 ), new String(
retrievePayload3 ) );
+
+ }
+
+}
Added:
incubator/directmemory/trunk/directmemory-cache/src/test/java/org/apache/directmemory/memory/test/RoundRobinAllocationPolicyTest.java
URL:
http://svn.apache.org/viewvc/incubator/directmemory/trunk/directmemory-cache/src/test/java/org/apache/directmemory/memory/test/RoundRobinAllocationPolicyTest.java?rev=1228174&view=auto
==============================================================================
---
incubator/directmemory/trunk/directmemory-cache/src/test/java/org/apache/directmemory/memory/test/RoundRobinAllocationPolicyTest.java
(added)
+++
incubator/directmemory/trunk/directmemory-cache/src/test/java/org/apache/directmemory/memory/test/RoundRobinAllocationPolicyTest.java
Fri Jan 6 13:41:13 2012
@@ -0,0 +1,202 @@
+package org.apache.directmemory.memory.test;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import junit.framework.Assert;
+
+import org.apache.directmemory.memory.OffHeapMemoryBuffer;
+import org.apache.directmemory.memory.Pointer;
+import org.apache.directmemory.memory.RoundRobinAllocationPolicy;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Unit test of {@link RoundRobinAllocationPolicy} class.
+ *
+ * @author [email protected]
+ *
+ */
+public class RoundRobinAllocationPolicyTest
+{
+
+ private static final int NUMBER_OF_BUFFERS = 4;
+
+ List<OffHeapMemoryBuffer> buffers;
+
+ RoundRobinAllocationPolicy allocationPolicy;
+
+ @Before
+ public void initAllocationPolicy()
+ {
+
+ buffers = new ArrayList<OffHeapMemoryBuffer>();
+
+ for ( int i = 0; i < NUMBER_OF_BUFFERS; i++ )
+ {
+ buffers.add( new DummyOffHeapMemoryBufferImpl() );
+ }
+
+ allocationPolicy = new RoundRobinAllocationPolicy();
+ allocationPolicy.setBuffers( buffers );
+ }
+
+ @Test
+ public void testSequence()
+ {
+
+ Assert.assertEquals( buffers.get( 0 ),
allocationPolicy.getActiveBuffer( null, 1 ) );
+ Assert.assertEquals( buffers.get( 1 ),
allocationPolicy.getActiveBuffer( null, 1 ) );
+ Assert.assertEquals( buffers.get( 2 ),
allocationPolicy.getActiveBuffer( null, 1 ) );
+ Assert.assertEquals( buffers.get( 3 ),
allocationPolicy.getActiveBuffer( null, 1 ) );
+ Assert.assertEquals( buffers.get( 0 ),
allocationPolicy.getActiveBuffer( null, 1 ) );
+ Assert.assertEquals( buffers.get( 1 ),
allocationPolicy.getActiveBuffer( null, 1 ) );
+ Assert.assertEquals( buffers.get( 2 ),
allocationPolicy.getActiveBuffer( null, 1 ) );
+ Assert.assertEquals( buffers.get( 3 ),
allocationPolicy.getActiveBuffer( null, 1 ) );
+
+ Assert.assertNotNull( allocationPolicy.getActiveBuffer( null, 1 ) );
+ Assert.assertNotNull( allocationPolicy.getActiveBuffer( null, 2 ) );
+ Assert.assertNull( allocationPolicy.getActiveBuffer( null, 3 ) );
+
+ allocationPolicy.reset();
+
+ Assert.assertEquals( buffers.get( 0 ),
allocationPolicy.getActiveBuffer( null, 1 ) );
+ Assert.assertEquals( buffers.get( 1 ),
allocationPolicy.getActiveBuffer( null, 1 ) );
+ Assert.assertEquals( buffers.get( 2 ),
allocationPolicy.getActiveBuffer( null, 1 ) );
+ Assert.assertEquals( buffers.get( 3 ),
allocationPolicy.getActiveBuffer( null, 1 ) );
+ Assert.assertEquals( buffers.get( 0 ),
allocationPolicy.getActiveBuffer( null, 1 ) );
+ Assert.assertEquals( buffers.get( 1 ),
allocationPolicy.getActiveBuffer( null, 1 ) );
+ Assert.assertEquals( buffers.get( 2 ),
allocationPolicy.getActiveBuffer( null, 1 ) );
+ Assert.assertEquals( buffers.get( 3 ),
allocationPolicy.getActiveBuffer( null, 1 ) );
+
+ }
+
+
+ @Test
+ public void testMaxAllocation()
+ {
+
+ allocationPolicy.setMaxAllocations( 1 );
+
+ Assert.assertNotNull( allocationPolicy.getActiveBuffer( null, 1 ) );
+ Assert.assertNull( allocationPolicy.getActiveBuffer( null, 2 ) );
+ Assert.assertNull( allocationPolicy.getActiveBuffer( null, 3 ) );
+
+ }
+
+
+ /**
+ * Dummy {@link OffHeapMemoryBuffer} that do nothing.
+ */
+ private static class DummyOffHeapMemoryBufferImpl
+ implements OffHeapMemoryBuffer
+ {
+
+ @Override
+ public int used()
+ {
+ return 0;
+ }
+
+ @Override
+ public int capacity()
+ {
+ return 0;
+ }
+
+ @Override
+ public int getBufferNumber()
+ {
+ return 0;
+ }
+
+ @Override
+ public Pointer store( byte[] payload )
+ {
+ return null;
+ }
+
+ @Override
+ public Pointer store( byte[] payload, Date expires )
+ {
+ return null;
+ }
+
+ @Override
+ public Pointer store( byte[] payload, long expiresIn )
+ {
+ return null;
+ }
+
+ @Override
+ public byte[] retrieve( Pointer pointer )
+ {
+ return null;
+ }
+
+ @Override
+ public int free( Pointer pointer2free )
+ {
+ return 0;
+ }
+
+ @Override
+ public void clear()
+ {
+ }
+
+ @Override
+ public void disposeExpiredRelative()
+ {
+ }
+
+ @Override
+ public void disposeExpiredAbsolute()
+ {
+ }
+
+ @Override
+ public long collectExpired()
+ {
+ return 0;
+ }
+
+ @Override
+ public long collectLFU( int limit )
+ {
+ return 0;
+ }
+
+ @Override
+ public Pointer update( Pointer pointer, byte[] payload )
+ {
+ return null;
+ }
+
+ @Override
+ public Pointer allocate( int size, long expiresIn, long expires )
+ {
+ return null;
+ }
+ }
+}