Clover icon

Coverage Report

  1. Project Clover database Thu Aug 13 2020 12:04:21 BST
  2. Package com.stevesoft.pat

File FastBracket.java

 

Coverage histogram

../../../img/srcFileCovDistChart8.png
20% of files have more coverage

Code metrics

56
101
10
1
257
200
43
0.43
10.1
10
4.3

Classes

Class Line # Actions
FastBracket 18 101 43
0.7844311678.4%
 

Contributing tests

This file is covered by 11 tests. .

Source view

1    //
2    // This software is now distributed according to
3    // the Lesser Gnu Public License. Please see
4    // http://www.gnu.org/copyleft/lesser.txt for
5    // the details.
6    // -- Happy Computing!
7    //
8    package com.stevesoft.pat;
9   
10    import java.util.BitSet;
11    import java.util.Vector;
12   
13    /**
14    * Uses table lookup to match [] type constructs, but only if it can use a
15    * lookup table 256 bits in size. It is impractical to make a table if it is too
16    * large.
17    */
 
18    public class FastBracket extends Bracket
19    {
20    int min, max;
21   
22    BitSet bs;
23   
 
24  474 toggle FastBracket(boolean n)
25    {
26  474 super(n);
27    }
28   
29    // This routine can optimize a bracket, possibly
30    // it will replace it with a FastBracket.
 
31  478 toggle static Bracket process(Bracket b, boolean ignc)
32    {
33  478 Vector v = b.v;
34  478 b.pv = null;
35  478 try
36    {
37   
38    // Expand out the vector to make separate
39    // entries for other cases if ignoreCase is
40    // turned on.
41  478 Vector nv = v;
42  478 if (ignc)
43    {
44  0 nv = new Vector();
45  0 for (int i = 0; i < v.size(); i++)
46    {
47  0 Pattern p = (Pattern) v.elementAt(i);
48  0 nv.addElement(p);
49  0 if (p instanceof oneChar)
50    {
51  0 oneChar oc = (oneChar) p;
52  0 nv.addElement(new oneChar(oc.altc));
53    }
54  0 else if (p instanceof Range)
55    {
56  0 Range ra = (Range) p;
57  0 nv.addElement(new Range(ra.altlo, ra.althi));
58    }
59    }
60    }
61  478 v = nv;
62   
63    // Bubble sort, make sure elements
64    // are in order. This will allow us
65    // to merge them.
66  1482 for (int i = 0; i < v.size() - 1; i++)
67    {
68  3208 for (int j = 0; j < v.size() - 1; j++)
69    {
70  2204 char c1 = getl(v.elementAt(j));
71  2204 char c2 = getl(v.elementAt(j + 1));
72  2204 if (c2 < c1)
73    {
74  1046 Object o = v.elementAt(j);
75  1046 v.setElementAt(v.elementAt(j + 1), j);
76  1046 v.setElementAt(o, j + 1);
77    }
78    }
79    }
80   
81  478 nv = new Vector();
82    // merge -- remove overlaps
83  478 Pattern p = (Pattern) v.elementAt(0);
84  478 nv.addElement(p);
85  1482 for (int i = 1; i < v.size(); i++)
86    {
87  1004 if (geth(p) + 1 >= getl(v.elementAt(i)))
88    {
89  48 Pattern p2 = (Pattern) v.elementAt(i);
90  48 char lo = min(getl(p), getl(p2));
91  48 char hi = max(geth(p), geth(p2));
92  48 nv.setElementAt(p = mkelem(lo, hi), nv.size() - 1);
93    }
94    else
95    {
96  956 p = (Pattern) v.elementAt(i);
97  956 nv.addElement(p);
98    }
99    }
100   
101  478 b.v = v = nv;
102    } catch (RegSyntax e)
103    {
104  0 e.printStackTrace();
105    }
106   
107    // We don't want these things to be empty.
108  478 Vector negv = neg(v);
109  478 if (v.size() == 1)
110    {
111  4 return b;
112    }
113  474 if (negv.size() == 1)
114    {
115  0 b.v = negv;
116  0 b.neg = !b.neg;
117  0 return b;
118    }
119   
120    // Now consider if we can make a FastBracket.
121    // Uses a BitSet to do a lookup.
122  474 FastBracket fb = newbrack(v, b.neg);
123  474 if (fb == null)
124    {
125  0 fb = newbrack(negv, !b.neg);
126    }
127  474 if (fb != null)
128    {
129  474 fb.parent = b.parent;
130  474 fb.next = b.next;
131  474 return fb;
132    }
133   
134    // return the normal Bracket.
135  0 return b;
136    }
137   
138    // Build a FastBracket and set bits. If this can't
139    // be done, return null.
 
140  474 toggle final static FastBracket newbrack(Vector v, boolean neg)
141    {
142  474 FastBracket fb = new FastBracket(neg);
143  474 fb.v = v;
144  474 if (v.size() == 0)
145    {
146  0 return null;
147    }
148  474 fb.min = getl(v.elementAt(0));
149  474 fb.max = geth(v.elementAt(v.size() - 1));
150  474 if (fb.max - fb.min <= 256)
151    {
152  474 fb.bs = new BitSet(fb.max - fb.min + 1);
153  1904 for (int i = 0; i < v.size(); i++)
154    {
155  1430 Object o = v.elementAt(i);
156  1430 int min0 = getl(o) - fb.min;
157  1430 int max0 = geth(o) - fb.min;
158  3908 for (int j = min0; j <= max0; j++)
159    {
160  2478 fb.bs.set(j);
161    }
162    }
163  474 return fb;
164    }
165  0 return null;
166    }
167   
168    // Negate a sorted Vector. Applying this
169    // operation twice should yield the same Vector
170    // back.
 
171  478 toggle final static Vector neg(Vector v)
172    {
173  478 try
174    {
175  478 Vector nv = new Vector();
176  478 if (v.size() == 0)
177    {
178  0 nv.addElement(new Range((char) 0, (char) 65535));
179  0 return nv;
180    }
181  478 int p0 = getl(v.elementAt(0));
182  478 if (p0 != 0)
183    {
184  474 nv.addElement(mkelem((char) 0, (char) (p0 - 1)));
185    }
186  1434 for (int i = 0; i < v.size() - 1; i++)
187    {
188  956 int hi = getl(v.elementAt(i + 1)) - 1;
189  956 int lo = geth(v.elementAt(i)) + 1;
190  956 nv.addElement(mkelem((char) lo, (char) hi));
191    }
192  478 int pN = geth(v.lastElement());
193  478 if (pN != 65535)
194    {
195  474 nv.addElement(mkelem((char) (pN + 1), (char) 65535));
196    }
197  478 return nv;
198    } catch (RegSyntax rs)
199    {
200  0 return null;
201    }
202    }
203   
204    // Make either a Range or oneChar Object, depending on which
205    // is appropriate.
 
206  1952 toggle final static Pattern mkelem(char lo, char hi) throws RegSyntax
207    {
208  1952 return lo == hi ? (Pattern) (new oneChar(lo)) : (Pattern) (new Range(
209    lo, hi));
210    }
211   
 
212  48 toggle static final char min(char a, char b)
213    {
214  48 return a < b ? a : b;
215    }
216   
 
217  48 toggle static final char max(char a, char b)
218    {
219  48 return a > b ? a : b;
220    }
221   
222    // getl -- get lower value of Range object,
223    // or get value of oneChar object.
 
224  8846 toggle final static char getl(Object o)
225    {
226  8846 Pattern p = (Pattern) o;
227  8846 if (p instanceof Range)
228    {
229  2318 return ((Range) p).lo;
230    }
231  6528 return ((oneChar) p).c;
232    }
233   
234    // geth -- get higher value of Range object,
235    // or get value of oneChar object.
 
236  4438 toggle final static char geth(Object o)
237    {
238  4438 Pattern p = (Pattern) o;
239  4438 if (p instanceof Range)
240    {
241  1456 return ((Range) p).hi;
242    }
243  2982 return ((oneChar) p).c;
244    }
245   
246    // This is the easy part!
 
247  212464 toggle public int matchInternal(int pos, Pthings pt)
248    {
249  212464 if (pos >= pt.src.length() || Masked(pos, pt))
250    {
251  4839 return -1;
252    }
253  207625 char c = pt.src.charAt(pos);
254  207625 return (neg ^ (c >= min && c <= max && bs.get(c - min))) ? nextMatch(
255    pos + 1, pt) : -1;
256    }
257    }