1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.giraph.object;
19
20 import org.apache.giraph.function.Consumer;
21 import org.apache.giraph.function.primitive.Int2ObjFunction;
22 import org.apache.giraph.types.ops.PrimitiveIdTypeOps;
23 import org.apache.giraph.types.ops.collections.Basic2ObjectMap;
24 import org.apache.giraph.types.ops.collections.BasicSet;
25
26 import com.google.common.base.Preconditions;
27
28 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
29
30
31
32
33
34
35
36
37
38
39
40
41
42 public class MultiSizedReusable<T> implements Int2ObjFunction<T> {
43 private final Int2ObjFunction<T> createSized;
44 private final Consumer<T> init;
45 @SuppressWarnings("unchecked")
46 @SuppressFBWarnings("SE_TRANSIENT_FIELD_NOT_RESTORED")
47 private final transient T[] holder = (T[]) new Object[Integer.SIZE];
48
49
50 MultiSizedReusable() {
51 this(null, null);
52 }
53
54 public MultiSizedReusable(Int2ObjFunction<T> createSized, Consumer<T> init) {
55 this.createSized = createSized;
56 this.init = init;
57 }
58
59 @Override
60 public T apply(int size) {
61 Preconditions.checkArgument(size >= 0);
62 int shiftBits = (Integer.SIZE -
63 Integer.numberOfLeadingZeros(Math.max(0, size - 1))) / 2;
64 T result = holder[shiftBits];
65 if (result == null) {
66 if (shiftBits >= 15) {
67 result = createSized.apply(Integer.MAX_VALUE);
68 } else {
69 result = createSized.apply(1 << (shiftBits * 2 + 1));
70 }
71 holder[shiftBits] = result;
72 }
73 if (init != null) {
74 init.apply(result);
75 }
76 return result;
77 }
78
79 public static <I> MultiSizedReusable<BasicSet<I>> createForBasicSet(
80 final PrimitiveIdTypeOps<I> idTypeOps) {
81 return new MultiSizedReusable<>(
82 new Int2ObjFunction<BasicSet<I>>() {
83 @Override
84 public BasicSet<I> apply(int value) {
85 return idTypeOps.createOpenHashSet(value);
86 }
87 },
88 new Consumer<BasicSet<I>>() {
89 @Override
90 public void apply(BasicSet<I> t) {
91 t.clear();
92 }
93 });
94 }
95
96 public static <K, V>
97 MultiSizedReusable<Basic2ObjectMap<K, V>> createForBasic2ObjectMap(
98 final PrimitiveIdTypeOps<K> idTypeOps) {
99 return new MultiSizedReusable<>(
100 new Int2ObjFunction<Basic2ObjectMap<K, V>>() {
101 @Override
102 public Basic2ObjectMap<K, V> apply(int value) {
103 return idTypeOps.create2ObjectOpenHashMap(value, null);
104 }
105 },
106 new Consumer<Basic2ObjectMap<K, V>>() {
107 @Override
108 public void apply(Basic2ObjectMap<K, V> t) {
109 t.clear();
110 }
111 });
112 }
113 }