private AvaialbeSegment getAvailableSegment(int size) {
        Deque<Segment> queue = null;
        int blockSize = 0;

        if (size <= 256) {
            queue = _queue256;
            blockSize = 256;
        } else if (size <= 384) {
            queue = _queue384;
            blockSize = 384;
        } else if (size <= 512) {
            queue = _queue512;
            blockSize = 512;
        } else if (size <= 640) {
            queue = _queue640;
            blockSize = 640;
        } else if (size <= 768) {
            queue = _queue768;
            blockSize = 768;
        } else if (size <= 896) {
            queue = _queue896;
            blockSize = 896;
        } else if (size <= 1024) {
            queue = _queue1024;
            blockSize = 1024;
        } else if (size <= 1280) {
            queue = _queue1280;
            blockSize = 1280;
        } else if (size <= 1536) {
            queue = _queue1536;
            blockSize = 1536;
        } else if (size <= 1792) {
            queue = _queue1792;
            blockSize = 1792;
        } else if (size <= 2048) {
            queue = _queue2048;
            blockSize = 2048;
        } else if (size <= 2560) {
            queue = _queue2560;
            blockSize = 2560;
        } else if (size <= 3072) {
            queue = _queue3072;
            blockSize = 3072;
        } else if (size <= 3584) {
            queue = _queue3584;
            blockSize = 3584;
        } else if (size <= 4096) {
            queue = _queue4096;
            blockSize = 4096;
        } else if (size <= 5120) {
            queue = _queue5120;
            blockSize = 5120;
        } else if (size <= 6144) {
            queue = _queue6144;
            blockSize = 6144;
        } else if (size <= 7168) {
            queue = _queue7168;
            blockSize = 7168;
        } else if (size <= 8192) {
            queue = _queue8192;
            blockSize = 8192;
        } else {
            throw new RuntimeException("Unsupported object size: " + size);
        }

        Segment segment = null;
        int availableBlockIndex = -1;

        synchronized (queue) {
            Iterator<Segment> iterator = queue.iterator();
            Iterator<Segment> descendingIterator = queue.descendingIterator();
            int half = queue.size() / 2 + 1;
            int cnt = 0;
            while (iterator.hasNext() && half-- > 0) {
                cnt++;
                segment = iterator.next();

                if ((availableBlockIndex = segment.allocate()) >= 0) {
                    if (cnt > 3) {
                        iterator.remove();
                        queue.addFirst(segment);
                    }

                    break;
                }

                segment = descendingIterator.next();

                if ((availableBlockIndex = segment.allocate()) >= 0) {
                    if (cnt > 3) {
                        descendingIterator.remove();
                        queue.addFirst(segment);
                    }

                    break;
                }
            }

            if (availableBlockIndex < 0) {
                synchronized (_segmentBitSet) {
                    int nextSegmentIndex = _segmentBitSet.nextClearBit(0);

                    if (nextSegmentIndex >= _segments.length) {
                        return null; // No space available;
                    }

                    segment = _segments[nextSegmentIndex];
                    _segmentBitSet.set(nextSegmentIndex);
                    _segmentQueueMap.put(nextSegmentIndex, queue);

                    segment.sizeOfBlock = blockSize;
                    queue.addFirst(segment);

                    availableBlockIndex = segment.allocate();
                }
            }
        }

        return new AvaialbeSegment(segment, availableBlockIndex);
    }
private AvaialbeSegment getAvailableSegment ( int size ) { Deque < Segment > queue = null ; int blockSize = 0 ; if ( size <= 256 ) { queue = _queue256 ; blockSize = 256 ; } else if ( size <= 384 ) { queue = _queue384 ; blockSize = 384 ; } else if ( size <= 512 ) { queue = _queue512 ; blockSize = 512 ; } else if ( size <= 640 ) { queue = _queue640 ; blockSize = 640 ; } else if ( size <= 768 ) { queue = _queue768 ; blockSize = 768 ; } else if ( size <= 896 ) { queue = _queue896 ; blockSize = 896 ; } else if ( size <= 1024 ) { queue = _queue1024 ; blockSize = 1024 ; } else if ( size <= 1280 ) { queue = _queue1280 ; blockSize = 1280 ; } else if ( size <= 1536 ) { queue = _queue1536 ; blockSize = 1536 ; } else if ( size <= 1792 ) { queue = _queue1792 ; blockSize = 1792 ; } else if ( size <= 2048 ) { queue = _queue2048 ; blockSize = 2048 ; } else if ( size <= 2560 ) { queue = _queue2560 ; blockSize = 2560 ; } else if ( size <= 3072 ) { queue = _queue3072 ; blockSize = 3072 ; } else if ( size <= 3584 ) { queue = _queue3584 ; blockSize = 3584 ; } else if ( size <= 4096 ) { queue = _queue4096 ; blockSize = 4096 ; } else if ( size <= 5120 ) { queue = _queue5120 ; blockSize = 5120 ; } else if ( size <= 6144 ) { queue = _queue6144 ; blockSize = 6144 ; } else if ( size <= 7168 ) { queue = _queue7168 ; blockSize = 7168 ; } else if ( size <= 8192 ) { queue = _queue8192 ; blockSize = 8192 ; } else { throw new RuntimeException ( "Unsupported object size: " + size ) ; } Segment segment = null ; int availableBlockIndex = - 1 ; synchronized ( queue ) { Iterator < Segment > iterator = queue . iterator ( ) ; Iterator < Segment > descendingIterator = queue . descendingIterator ( ) ; int half = queue . size ( ) / 2 + 1 ; int cnt = 0 ; while ( iterator . hasNext ( ) && half -- > 0 ) { cnt ++ ; segment = iterator . next ( ) ; if ( ( availableBlockIndex = segment . allocate ( ) ) >= 0 ) { if ( cnt > 3 ) { iterator . remove ( ) ; queue . addFirst ( segment ) ; } break ; } segment = descendingIterator . next ( ) ; if ( ( availableBlockIndex = segment . allocate ( ) ) >= 0 ) { if ( cnt > 3 ) { descendingIterator . remove ( ) ; queue . addFirst ( segment ) ; } break ; } } if ( availableBlockIndex < 0 ) { synchronized ( _segmentBitSet ) { int nextSegmentIndex = _segmentBitSet . nextClearBit ( 0 ) ; if ( nextSegmentIndex >= _segments . length ) { return null ; } segment = _segments [ nextSegmentIndex ] ; _segmentBitSet . set ( nextSegmentIndex ) ; _segmentQueueMap . put ( nextSegmentIndex , queue ) ; segment . sizeOfBlock = blockSize ; queue . addFirst ( segment ) ; availableBlockIndex = segment . allocate ( ) ; } } } return new AvaialbeSegment ( segment , availableBlockIndex ) ; }
TODO: performance tuning for concurrent put.