~smaioli/azureus/ubuntu-experimental

« back to all changes in this revision

Viewing changes to org/gudy/azureus2/core3/util/DirectByteBufferPoolHeap.java

MergedĀ VuzeĀ 4.0.0.4.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Created on Nov 4, 2008
 
3
 * Created by Paul Gardner
 
4
 * 
 
5
 * Copyright 2008 Vuze, Inc.  All rights reserved.
 
6
 * 
 
7
 * This program is free software; you can redistribute it and/or modify
 
8
 * it under the terms of the GNU General Public License as published by
 
9
 * the Free Software Foundation; version 2 of the License only.
 
10
 * 
 
11
 * This program is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 
14
 * GNU General Public License for more details.
 
15
 * 
 
16
 * You should have received a copy of the GNU General Public License
 
17
 * along with this program; if not, write to the Free Software
 
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 
19
 */
 
20
 
 
21
 
 
22
package org.gudy.azureus2.core3.util;
 
23
 
 
24
import java.util.*;
 
25
import java.nio.ByteBuffer;
 
26
 
 
27
public class 
 
28
DirectByteBufferPoolHeap
 
29
        extends DirectByteBufferPool
 
30
{
 
31
        private final boolean USE_POOLS = false;
 
32
        
 
33
        private final boolean TRACE     = false;
 
34
        
 
35
        private final int MIN_POOL;
 
36
        private final int MAX_POOL;
 
37
        
 
38
 
 
39
        private final LinkedList[]              pools;
 
40
        private final int[]                             pool_sizes;
 
41
 
 
42
        private Map     sizes;
 
43
        
 
44
        protected
 
45
        DirectByteBufferPoolHeap()
 
46
        {
 
47
                        /**
 
48
                         * On linux (at least) JDK1.7.0 using heap buffers doesn't play well as the JVM still
 
49
                         * goes and creates DirectByteBuffers under the covers and things run out of control
 
50
                         * (after a few mins I have a 9GB VM...)
 
51
                         */
 
52
                
 
53
                if ( USE_POOLS ){
 
54
                        
 
55
                        pool_sizes = new int[]{ 
 
56
                                        2*1024, 
 
57
                                        4*1024+128, 
 
58
                                        8*1024+128,
 
59
                                        16*1024+128,
 
60
                                        32*1024+128,
 
61
                                        64*1024+128,
 
62
                                        128*1024+128,
 
63
                                        256*1024 };
 
64
                        
 
65
                        MIN_POOL        = pool_sizes[0];
 
66
                        MAX_POOL        = pool_sizes[pool_sizes.length-1];
 
67
                        
 
68
                        pools = new LinkedList[ pool_sizes.length ];
 
69
                        
 
70
                        for (int i=0;i<pools.length;i++){
 
71
                                
 
72
                                pools[i] = new LinkedList();
 
73
                        }
 
74
                        
 
75
                        if ( TRACE ){
 
76
                                
 
77
                                sizes           = new TreeMap();
 
78
        
 
79
                                SimpleTimer.addPeriodicEvent(
 
80
                                        "HeapPoolDumper",
 
81
                                        5000,
 
82
                                        new TimerEventPerformer()
 
83
                                        {
 
84
                                                public void 
 
85
                                                perform(
 
86
                                                        TimerEvent event ) 
 
87
                                                {
 
88
                                                        synchronized( sizes ){
 
89
                                                                
 
90
                                                                String  str = "";
 
91
                                                                
 
92
                                                                Iterator it = sizes.entrySet().iterator();
 
93
                                                                
 
94
                                                                while( it.hasNext()){
 
95
                                                                        
 
96
                                                                        Map.Entry       entry = (Map.Entry)it.next();
 
97
                                                                        
 
98
                                                                        str += (str.length()==0?"":",") + entry.getKey() + "->" + entry.getValue();
 
99
                                                                }
 
100
                                                                
 
101
                                                                System.out.println( "HB allocs: " + str );
 
102
                                                        }
 
103
                                                }
 
104
                                        });
 
105
                        }
 
106
                }else{
 
107
                        
 
108
                        MIN_POOL = MAX_POOL = 0;
 
109
                        
 
110
                        pools           = null;
 
111
                        pool_sizes      = null;
 
112
                }
 
113
        }
 
114
        
 
115
        protected DirectByteBuffer
 
116
        getBufferSupport(
 
117
                byte            allocator,
 
118
                int                     length )
 
119
        {
 
120
                if ( USE_POOLS ){
 
121
                        
 
122
                        if ( TRACE ){
 
123
                                
 
124
                                synchronized( sizes ){
 
125
                                        
 
126
                                        Integer key = new Integer( length/32*32 );
 
127
                                        
 
128
                                        Integer count = (Integer)sizes.get( key );
 
129
                                        
 
130
                                        if ( count == null ){
 
131
                                                
 
132
                                                sizes.put( key, new Integer(1));
 
133
                                                
 
134
                                        }else{
 
135
                                                
 
136
                                                sizes.put( key, new Integer( count.intValue() + 1 ));
 
137
                                        }
 
138
                                }
 
139
                        }
 
140
                        
 
141
                        int     pool_index = getPoolIndex( length );
 
142
                        
 
143
                        if ( pool_index != -1 ){
 
144
                                
 
145
                                LinkedList pool = pools[pool_index];
 
146
                                                        
 
147
                                synchronized( pool ){
 
148
                                        
 
149
                                        if ( !pool.isEmpty()){
 
150
                                                
 
151
                                                Object[] entry = (Object[])pool.removeLast();
 
152
                                                
 
153
                                                ByteBuffer buff = (ByteBuffer)entry[0];
 
154
                                                
 
155
                                        buff.clear();
 
156
                                        
 
157
                                                buff.limit( length );
 
158
                                                
 
159
                                                return( new DirectByteBuffer( allocator, buff, this ));
 
160
                                        }
 
161
                                }       
 
162
        
 
163
                                DirectByteBuffer        buffer = new DirectByteBuffer( allocator, ByteBuffer.allocate( pool_sizes[pool_index] ), this );
 
164
                                
 
165
                                ByteBuffer buff = buffer.getBufferInternal();
 
166
                                                
 
167
                                buff.limit( length );
 
168
                                
 
169
                                return( buffer );
 
170
        
 
171
                        }else{
 
172
                        
 
173
                                return( new DirectByteBuffer( allocator, ByteBuffer.allocate( length ), this ));
 
174
                        }
 
175
                }else{
 
176
                        
 
177
                        return( new DirectByteBuffer( allocator, ByteBuffer.allocate( length ), this ));
 
178
                }
 
179
        }
 
180
        
 
181
        protected void
 
182
        returnBufferSupport(
 
183
                DirectByteBuffer        buffer )
 
184
        {
 
185
                if ( USE_POOLS ){
 
186
                        
 
187
                        ByteBuffer      buff = buffer.getBufferInternal();
 
188
                        
 
189
                        int     length = buff.capacity();
 
190
                        
 
191
                        int     pool_index = getPoolIndex( length );
 
192
                        
 
193
                        if ( pool_index != -1 ){
 
194
                                
 
195
                                LinkedList pool = pools[pool_index];
 
196
                                
 
197
                                synchronized( pool ){
 
198
                                        
 
199
                                        pool.addLast( new Object[]{ buff });
 
200
                                }
 
201
                        }
 
202
                }
 
203
        }
 
204
        
 
205
        protected int
 
206
        getPoolIndex(
 
207
                int             length )
 
208
        {
 
209
                if ( length < MIN_POOL|| length > MAX_POOL ){
 
210
                        
 
211
                        return( -1 );
 
212
                }
 
213
                
 
214
                for (int i=0;i<pool_sizes.length;i++){
 
215
                        
 
216
                        if ( length <= pool_sizes[i] ){
 
217
                                
 
218
                                return( i );
 
219
                        }
 
220
                }
 
221
                
 
222
                return( -1 );
 
223
        }
 
224
}