38
38
import static org .jruby .anno .FrameField .BACKREF ;
39
39
import static org .jruby .anno .FrameField .LASTLINE ;
40
40
41
- import java .lang .ref .SoftReference ;
42
- import java .util .Iterator ;
43
- import java .util .Map ;
44
- import java .util .concurrent .ConcurrentHashMap ;
45
-
46
41
import org .jcodings .Encoding ;
47
42
import org .jcodings .specific .ASCIIEncoding ;
48
43
import org .jcodings .specific .USASCIIEncoding ;
78
73
import org .jruby .util .Sprintf ;
79
74
import org .jruby .util .StringSupport ;
80
75
import org .jruby .util .TypeConverter ;
76
+ import org .jruby .util .collections .WeakValuedMap ;
77
+
78
+ import java .util .Iterator ;
81
79
82
80
@ JRubyClass (name ="Regexp" )
83
81
public class RubyRegexp extends RubyObject implements ReOptions , EncodingCapable , MarshalEncoding {
@@ -140,22 +138,10 @@ public boolean shouldMarshalEncoding() {
140
138
public Encoding getMarshalEncoding () {
141
139
return getEncoding ();
142
140
}
143
-
144
- private static final class RegexpCache {
145
- private volatile SoftReference <Map <ByteList , Regex >> cache = new SoftReference <Map <ByteList , Regex >>(null );
146
- private Map <ByteList , Regex > get () {
147
- Map <ByteList , Regex > patternCache = cache .get ();
148
- if (patternCache == null ) {
149
- patternCache = new ConcurrentHashMap <ByteList , Regex >(5 );
150
- cache = new SoftReference <Map <ByteList , Regex >>(patternCache );
151
- }
152
- return patternCache ;
153
- }
154
- }
155
-
156
- private static final RegexpCache patternCache = new RegexpCache ();
157
- private static final RegexpCache quotedPatternCache = new RegexpCache ();
158
- private static final RegexpCache preprocessedPatternCache = new RegexpCache ();
141
+ // FIXME: Maybe these should not be static?
142
+ private static final WeakValuedMap <ByteList , Regex > patternCache = new WeakValuedMap ();
143
+ private static final WeakValuedMap <ByteList , Regex > quotedPatternCache = new WeakValuedMap ();
144
+ private static final WeakValuedMap <ByteList , Regex > preprocessedPatternCache = new WeakValuedMap ();
159
145
160
146
private static Regex makeRegexp (Ruby runtime , ByteList bytes , RegexpOptions options , Encoding enc ) {
161
147
try {
@@ -172,46 +158,42 @@ private static Regex makeRegexp(Ruby runtime, ByteList bytes, RegexpOptions opti
172
158
}
173
159
174
160
static Regex getRegexpFromCache (Ruby runtime , ByteList bytes , Encoding enc , RegexpOptions options ) {
175
- Map <ByteList , Regex > cache = patternCache .get ();
176
- Regex regex = cache .get (bytes );
161
+ Regex regex = patternCache .get (bytes );
177
162
if (regex != null && regex .getEncoding () == enc && regex .getOptions () == options .toJoniOptions ()) return regex ;
178
163
regex = makeRegexp (runtime , bytes , options , enc );
179
164
regex .setUserObject (bytes );
180
- cache .put (bytes , regex );
165
+ patternCache .put (bytes , regex );
181
166
return regex ;
182
167
}
183
168
184
169
static Regex getQuotedRegexpFromCache (Ruby runtime , ByteList bytes , Encoding enc , RegexpOptions options ) {
185
- Map <ByteList , Regex > cache = quotedPatternCache .get ();
186
- Regex regex = cache .get (bytes );
170
+ Regex regex = quotedPatternCache .get (bytes );
187
171
if (regex != null && regex .getEncoding () == enc && regex .getOptions () == options .toJoniOptions ()) return regex ;
188
172
ByteList quoted = quote (bytes , enc );
189
173
regex = makeRegexp (runtime , quoted , options , enc );
190
174
regex .setUserObject (quoted );
191
- cache .put (bytes , regex );
175
+ quotedPatternCache .put (bytes , regex );
192
176
return regex ;
193
177
}
194
178
195
179
static Regex getQuotedRegexpFromCache19 (Ruby runtime , ByteList bytes , RegexpOptions options , boolean asciiOnly ) {
196
- Map <ByteList , Regex > cache = quotedPatternCache .get ();
197
- Regex regex = cache .get (bytes );
180
+ Regex regex = quotedPatternCache .get (bytes );
198
181
Encoding enc = asciiOnly ? USASCIIEncoding .INSTANCE : bytes .getEncoding ();
199
182
if (regex != null && regex .getEncoding () == enc && regex .getOptions () == options .toJoniOptions ()) return regex ;
200
183
ByteList quoted = quote19 (bytes , asciiOnly );
201
184
regex = makeRegexp (runtime , quoted , options , quoted .getEncoding ());
202
185
regex .setUserObject (quoted );
203
- cache .put (bytes , regex );
186
+ quotedPatternCache .put (bytes , regex );
204
187
return regex ;
205
188
}
206
189
207
190
private static Regex getPreprocessedRegexpFromCache (Ruby runtime , ByteList bytes , Encoding enc , RegexpOptions options , ErrorMode mode ) {
208
- Map <ByteList , Regex > cache = preprocessedPatternCache .get ();
209
- Regex regex = cache .get (bytes );
191
+ Regex regex = preprocessedPatternCache .get (bytes );
210
192
if (regex != null && regex .getEncoding () == enc && regex .getOptions () == options .toJoniOptions ()) return regex ;
211
193
ByteList preprocessed = preprocess (runtime , bytes , enc , new Encoding []{null }, ErrorMode .RAISE );
212
194
regex = makeRegexp (runtime , preprocessed , options , enc );
213
195
regex .setUserObject (preprocessed );
214
- cache .put (bytes , regex );
196
+ preprocessedPatternCache .put (bytes , regex );
215
197
return regex ;
216
198
}
217
199
0 commit comments