13c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller/* 23c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * Copyright (C) 2014 Square, Inc. 33c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * 43c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * Licensed under the Apache License, Version 2.0 (the "License"); 53c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * you may not use this file except in compliance with the License. 63c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * You may obtain a copy of the License at 73c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * 83c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * http://www.apache.org/licenses/LICENSE-2.0 93c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * 103c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * Unless required by applicable law or agreed to in writing, software 113c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * distributed under the License is distributed on an "AS IS" BASIS, 123c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * See the License for the specific language governing permissions and 143c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * limitations under the License. 153c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller */ 163c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerpackage okio; 173c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 183c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller/** 193c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * A collection of unused segments, necessary to avoid GC churn and zero-fill. 203c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller * This pool is a thread-safe static singleton. 213c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller */ 223c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fullerfinal class SegmentPool { 233c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller static final SegmentPool INSTANCE = new SegmentPool(); 243c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 253c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller /** The maximum number of bytes to pool. */ 263c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller // TODO: Is 64 KiB a good maximum size? Do we ever have that many idle segments? 273c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller static final long MAX_SIZE = 64 * 1024; // 64 KiB. 283c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 293c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller /** Singly-linked list of segments. */ 303c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller private Segment next; 313c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 323c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller /** Total bytes in this pool. */ 333c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller long byteCount; 343c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 353c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller private SegmentPool() { 363c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 373c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 383c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller Segment take() { 393c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller synchronized (this) { 403c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller if (next != null) { 413c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller Segment result = next; 423c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller next = result.next; 433c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller result.next = null; 443c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller byteCount -= Segment.SIZE; 453c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller return result; 463c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 473c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 483c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller return new Segment(); // Pool is empty. Don't zero-fill while holding a lock. 493c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 503c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller 513c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller void recycle(Segment segment) { 523c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller if (segment.next != null || segment.prev != null) throw new IllegalArgumentException(); 533c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller synchronized (this) { 543c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller if (byteCount + Segment.SIZE > MAX_SIZE) return; // Pool is full. 553c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller byteCount += Segment.SIZE; 563c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller segment.next = next; 573c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller segment.pos = segment.limit = 0; 583c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller next = segment; 593c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 603c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller } 613c938a3f6b61ce5e2dba0d039b03fe73b89fd26cNeil Fuller} 62