1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 package org.spf4j.recyclable.impl;
33
34 import java.lang.ref.Reference;
35 import java.util.ArrayDeque;
36 import java.util.Deque;
37 import org.spf4j.base.IntMath;
38 import org.spf4j.base.ReferenceType;
39 import org.spf4j.recyclable.SizedRecyclingSupplier;
40
41
42
43
44
45
46 public final class Powerof2ThreadLocalRecyclingSupplier<T> implements SizedRecyclingSupplier<T> {
47
48 private final SizedRecyclingSupplier.Factory<T> factory;
49
50 private final ReferenceType refType;
51
52 private final ThreadLocal<Deque<Reference<T>> []> localObjects;
53
54 public Powerof2ThreadLocalRecyclingSupplier(final Factory<T> factory, final ReferenceType refType) {
55 this.factory = factory;
56 this.refType = refType;
57 localObjects = new ThreadLocal<Deque<Reference<T>> []>() {
58
59 @Override
60 protected Deque<Reference<T>>[] initialValue() {
61 Deque<Reference<T>>[] result = new Deque[28];
62 for (int i = 0; i < result.length; i++) {
63 result[i] = new ArrayDeque<>();
64 }
65 return result;
66 }
67 };
68 }
69
70 @Override
71 public T get(final int size) {
72 Deque<Reference<T>>[] available = localObjects.get();
73 int idx = IntMath.closestPowerOf2(size);
74 Deque<Reference<T>> refs = available[idx];
75 if (refs.isEmpty()) {
76 int actualSize = 1 << idx;
77 return factory.create(actualSize);
78 } else {
79 T result;
80 do {
81 Reference<T> removeLast = refs.removeLast();
82 result = removeLast.get();
83 } while (result == null && !refs.isEmpty());
84 if (result == null) {
85 int actualSize = 1 << idx;
86 return factory.create(actualSize);
87 } else {
88 return result;
89 }
90 }
91 }
92
93 @Override
94 public void recycle(final T object) {
95 int size = factory.size(object);
96 int idx = IntMath.closestPowerOf2(size);
97 Deque<Reference<T>>[] available = localObjects.get();
98 Deque<Reference<T>> refs = available[idx];
99 refs.addLast(refType.create(object));
100 }
101
102 @Override
103 public String toString() {
104 return "Powerof2ThreadLocalRecyclingSupplier{" + "factory=" + factory + ", refType=" + refType + '}';
105 }
106
107 }