/**
  * Returns the block of size equal or greater than current size for reallocation which is marked
  * as free.
  *
  * @param capacity
  * @return null when it fails to search a valid sized block
  */
 private Pointer firstMatch(int capacity) {
   synchronized (pointers) {
     for (Pointer ptr : pointers) {
       // Find a frame with right size. Comapaction problems to be dealt.
       if (ptr.isFree() && (ptr.getEnd() - ptr.getStart()) > capacity) {
         return ptr;
       }
     }
   }
   return null;
 }
 /*
  * (non-Javadoc)
  *
  * @see com.prashant.memory.MemoryBuffer#update(com.prashant.memory.Pointer, byte[], int)
  */
 public void update(Pointer pointer, byte[] payload, int offset)
     throws DMFrameLimitExcededException {
   if (pointer.getStart() + offset + payload.length - 1 <= pointer.getEnd()) {
     ByteBuffer buf;
     synchronized (buffer) {
       buf = buffer.duplicate();
     }
     buf.position(pointer.getStart() + offset);
     buf.put(payload);
     return;
   }
   throw new DMFrameLimitExcededException(
       "Trying to write to a position out of bounds for this pointer.", null);
 }
 /**
  * Resize an existing block to new capacity by slicing the <code>Pointer</code> pointed to by
  * existing pointer. The new <code>Pointer</code> is a slice present before the existing.
  *
  * @param existing points to existing Pointer(referring existing block).
  * @param capacity to be resized to.
  * @return Pointer to resized block.
  */
 private Pointer slice(Pointer existing, int capacity) {
   if ((existing.getEnd() - existing.getStart()) == capacity + 1 && existing.isFree()) {
     return existing;
   }
   Pointer fresh = new Pointer();
   fresh.setBlockNumber(existing.getBlockNumber());
   fresh.setStart(existing.getStart());
   fresh.setEnd(fresh.getStart() + capacity);
   fresh.setFree(true);
   fresh.setPrev(existing.getPrev());
   existing.setPrev(fresh);
   fresh.setNext(existing);
   existing.setStart(existing.getStart() + (capacity + 1));
   return fresh;
 }
 /*
  * (non-Javadoc)
  *
  * @see com.prashant.memory.MemoryBuffer#retrieve(com.prashant.memory.Pointer, int, int)
  */
 public byte[] retrieve(Pointer pointer, int offset, int len) throws DMFrameLimitExcededException {
   int checkLength = pointer.getStart() + offset + len;
   ByteBuffer buf = null;
   if (checkLength <= pointer.getEnd()) {
     synchronized (buffer) {
       buf = buffer.duplicate();
     }
     buf.position(pointer.getStart() + offset);
     final byte[] swp = new byte[len];
     buf.get(swp);
     return swp;
   }
   throw new DMFrameLimitExcededException(
       "Trying to read to a position out of bounds for this pointer.", null);
 }
 /*
  * (non-Javadoc)
  *
  * @see com.prashant.memory.MemoryBuffer#free(com.prashant.memory.Pointer)
  */
 public long free(Pointer pointer2free) {
   used.addAndGet(-(pointer2free.getEnd() - pointer2free.getStart()));
   freeAndMerge(pointer2free);
   return pointer2free.getEnd() - pointer2free.getStart();
 }
 /*
  * (non-Javadoc)
  *
  * @see com.prashant.memory.MemoryBuffer#retrieve(com.prashant.memory.Pointer)
  */
 public byte[] retrieve(Pointer pointer) throws DMFrameLimitExcededException {
   return retrieve(pointer, 0, pointer.getEnd() - pointer.getStart());
 }