1
+ /*
2
+ * Copyright (C) 2011 the original author or authors.
3
+ * See the NOTICE file distributed with this work for additional
4
+ * information regarding copyright ownership.
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+ package org .xerial .snappy ;
19
+ import java .lang .ref .SoftReference ;
20
+
21
+ /**
22
+ * Simple helper class to encapsulate details of basic buffer
23
+ * recycling scheme, which helps a lot (as per profiling) for
24
+ * smaller encoding cases.
25
+ *
26
+ * @author tatu
27
+ */
28
+ class BufferRecycler
29
+ {
30
+ private final static int MIN_ENCODING_BUFFER = 4000 ;
31
+
32
+ private final static int MIN_OUTPUT_BUFFER = 8000 ;
33
+
34
+ /**
35
+ * This <code>ThreadLocal</code> contains a {@link java.lang.ref.SoftReference}
36
+ * to a {@link BufferRecycler} used to provide a low-cost
37
+ * buffer recycling for buffers we need for encoding, decoding.
38
+ */
39
+ final protected static ThreadLocal <SoftReference <BufferRecycler >> recyclerRef
40
+ = new ThreadLocal <SoftReference <BufferRecycler >>();
41
+
42
+
43
+ private byte [] inputBuffer ;
44
+ private byte [] outputBuffer ;
45
+
46
+ private byte [] decodingBuffer ;
47
+ private byte [] encodingBuffer ;
48
+
49
+ private short [] encodingHash ;
50
+
51
+
52
+ /**
53
+ * Accessor to get thread-local recycler instance
54
+ */
55
+ public static BufferRecycler instance ()
56
+ {
57
+ SoftReference <BufferRecycler > ref = recyclerRef .get ();
58
+
59
+ BufferRecycler bufferRecycler ;
60
+ if (ref == null ) {
61
+ bufferRecycler = null ;
62
+ }
63
+ else {
64
+ bufferRecycler = ref .get ();
65
+ }
66
+
67
+ if (bufferRecycler == null ) {
68
+ bufferRecycler = new BufferRecycler ();
69
+ recyclerRef .set (new SoftReference <BufferRecycler >(bufferRecycler ));
70
+ }
71
+ return bufferRecycler ;
72
+ }
73
+
74
+ ///////////////////////////////////////////////////////////////////////
75
+ // Buffers for encoding (output)
76
+ ///////////////////////////////////////////////////////////////////////
77
+
78
+ public byte [] allocEncodingBuffer (int minSize )
79
+ {
80
+ byte [] buf = encodingBuffer ;
81
+ if (buf == null || buf .length < minSize ) {
82
+ buf = new byte [Math .max (minSize , MIN_ENCODING_BUFFER )];
83
+ }
84
+ else {
85
+ encodingBuffer = null ;
86
+ }
87
+ return buf ;
88
+ }
89
+
90
+ public void releaseEncodeBuffer (byte [] buffer )
91
+ {
92
+ if (encodingBuffer == null || buffer .length > encodingBuffer .length ) {
93
+ encodingBuffer = buffer ;
94
+ }
95
+ }
96
+
97
+ public byte [] allocOutputBuffer (int minSize )
98
+ {
99
+ byte [] buf = outputBuffer ;
100
+ if (buf == null || buf .length < minSize ) {
101
+ buf = new byte [Math .max (minSize , MIN_OUTPUT_BUFFER )];
102
+ }
103
+ else {
104
+ outputBuffer = null ;
105
+ }
106
+ return buf ;
107
+ }
108
+
109
+ public void releaseOutputBuffer (byte [] buffer )
110
+ {
111
+ if (outputBuffer == null || (buffer != null && buffer .length > outputBuffer .length )) {
112
+ outputBuffer = buffer ;
113
+ }
114
+ }
115
+
116
+ public short [] allocEncodingHash (int suggestedSize )
117
+ {
118
+ short [] buf = encodingHash ;
119
+ if (buf == null || buf .length < suggestedSize ) {
120
+ buf = new short [suggestedSize ];
121
+ }
122
+ else {
123
+ encodingHash = null ;
124
+ }
125
+ return buf ;
126
+ }
127
+
128
+ public void releaseEncodingHash (short [] buffer )
129
+ {
130
+ if (encodingHash == null || (buffer != null && buffer .length > encodingHash .length )) {
131
+ encodingHash = buffer ;
132
+ }
133
+ }
134
+
135
+ ///////////////////////////////////////////////////////////////////////
136
+ // Buffers for decoding (input)
137
+ ///////////////////////////////////////////////////////////////////////
138
+
139
+ public byte [] allocInputBuffer (int minSize )
140
+ {
141
+ byte [] buf = inputBuffer ;
142
+ if (buf == null || buf .length < minSize ) {
143
+ buf = new byte [Math .max (minSize , MIN_OUTPUT_BUFFER )];
144
+ }
145
+ else {
146
+ inputBuffer = null ;
147
+ }
148
+ return buf ;
149
+ }
150
+
151
+ public void releaseInputBuffer (byte [] buffer )
152
+ {
153
+ if (inputBuffer == null || (buffer != null && buffer .length > inputBuffer .length )) {
154
+ inputBuffer = buffer ;
155
+ }
156
+ }
157
+
158
+ public byte [] allocDecodeBuffer (int size )
159
+ {
160
+ byte [] buf = decodingBuffer ;
161
+ if (buf == null || buf .length < size ) {
162
+ buf = new byte [size ];
163
+ }
164
+ else {
165
+ decodingBuffer = null ;
166
+ }
167
+ return buf ;
168
+ }
169
+
170
+ public void releaseDecodeBuffer (byte [] buffer )
171
+ {
172
+ if (decodingBuffer == null || (buffer != null && buffer .length > decodingBuffer .length )) {
173
+ decodingBuffer = buffer ;
174
+ }
175
+ }
176
+ }
0 commit comments