protected long allocateCharChunk(final char[] src, final int start, final int length) {
   assert (length < CHUNKED_THRESHOLD) : length;
   final int reqlen = length + 1; // actual length is store in first char.
   final long lpage;
   if (((_cpointer & BLOCK_MASK) + reqlen) > DEFAULT_BLOCK_SIZE_L) {
     // spanning pages is not allowed, allocate in next chunk.
     lpage = (_cpointer >> BLOCK_SHIFT) + 1;
     _cpointer = lpage * DEFAULT_BLOCK_SIZE_L;
   } else {
     lpage = _cpointer >> BLOCK_SHIFT;
   }
   final int page = (int) lpage;
   if (page >= _cchunks.length) {
     enlarge((int) (_cchunks.length * ENLARGE_PAGES_FACTOR));
   }
   if (_cchunks[page] == null) {
     _cchunks[page] = new char[DEFAULT_BLOCK_SIZE];
   }
   final long lblock = _cpointer & BLOCK_MASK;
   final int block = (int) lblock;
   assert (length <= Character.MAX_VALUE) : length;
   _cchunks[page][block] = (char) length;
   System.arraycopy(src, start, _cchunks[page], block + 1, length);
   final long index = _cpointer;
   _cpointer += reqlen; // move ahead pointer
   return chunkKey(index);
 }
 @Override
 protected void enlarge(final int pages) {
   ++enlarged;
   if (enlarged >= paging_threshold) {
     try {
       pagedOut();
     } catch (IOException e) {
       throw new IllegalStateException("page out failed", e);
     }
     paging_threshold = Math.max(2, (int) (paging_threshold * 0.8));
     enlarged = 0;
   }
   super.enlarge(pages);
 }