1/*
2 * Copyright (C) 2014 Square, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package okio;
17
18/**
19 * A collection of unused segments, necessary to avoid GC churn and zero-fill.
20 * This pool is a thread-safe static singleton.
21 */
22final class SegmentPool {
23  /** The maximum number of bytes to pool. */
24  // TODO: Is 64 KiB a good maximum size? Do we ever have that many idle segments?
25  static final long MAX_SIZE = 64 * 1024; // 64 KiB.
26
27  /** Singly-linked list of segments. */
28  static Segment next;
29
30  /** Total bytes in this pool. */
31  static long byteCount;
32
33  private SegmentPool() {
34  }
35
36  static Segment take() {
37    synchronized (SegmentPool.class) {
38      if (next != null) {
39        Segment result = next;
40        next = result.next;
41        result.next = null;
42        byteCount -= Segment.SIZE;
43        return result;
44      }
45    }
46    return new Segment(); // Pool is empty. Don't zero-fill while holding a lock.
47  }
48
49  static void recycle(Segment segment) {
50    if (segment.next != null || segment.prev != null) throw new IllegalArgumentException();
51    if (segment.shared) return; // This segment cannot be recycled.
52    synchronized (SegmentPool.class) {
53      if (byteCount + Segment.SIZE > MAX_SIZE) return; // Pool is full.
54      byteCount += Segment.SIZE;
55      segment.next = next;
56      segment.pos = segment.limit = 0;
57      next = segment;
58    }
59  }
60}
61