* RegexTest.cs: Add some simple tests for debugging/zen
[mono.git] / mcs / class / System / System.Text.RegularExpressions / cache.cs
1 //\r
2 // assembly:    System\r
3 // namespace:   System.Text.RegularExpressions\r
4 // file:        cache.cs\r
5 //\r
6 // author:      Dan Lewis (dlewis@gmx.co.uk)\r
7 //              (c) 2002\r
8
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 // 
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 // 
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 //
29 \r
30 using System;\r
31 using System.Collections;\r
32 \r
33 namespace System.Text.RegularExpressions {\r
34 \r
35         class FactoryCache {\r
36                 public FactoryCache (int capacity) {\r
37                         this.capacity = capacity;\r
38                         this.factories = new Hashtable (capacity);\r
39                         this.mru_list = new MRUList ();\r
40                 }\r
41 \r
42                 public void Add (string pattern, RegexOptions options, IMachineFactory factory) {\r
43                         lock (this) {\r
44                                 Key k = new Key (pattern, options);\r
45 \r
46                                 while (factories.Count >= capacity) {\r
47                                         object victim = mru_list.Evict ();\r
48                                         if (victim != null)\r
49                                                 factories.Remove ((Key)victim);\r
50                                 }\r
51                                 \r
52                                 factories[k] = factory;\r
53                                 mru_list.Use (k);\r
54                         }\r
55                 }\r
56 \r
57                 public IMachineFactory Lookup (string pattern, RegexOptions options) {\r
58                         lock (this) {\r
59                                 Key k = new Key (pattern, options);\r
60                                 if (factories.Contains (k)) {\r
61                                         mru_list.Use (k);\r
62                                         return (IMachineFactory)factories[k];\r
63                                 }\r
64                         }\r
65 \r
66                         return null;\r
67                 }\r
68 \r
69                 private int capacity;\r
70                 private Hashtable factories;\r
71                 private MRUList mru_list;\r
72 \r
73                 class Key {\r
74                         public string pattern;\r
75                         public RegexOptions options;\r
76 \r
77                         public Key (string pattern, RegexOptions options) {\r
78                                 this.pattern = pattern;\r
79                                 this.options = options;\r
80                         }\r
81                         \r
82                         public override int GetHashCode () {\r
83                                 return pattern.GetHashCode () ^ (int)options;\r
84                         }\r
85 \r
86                         public override bool Equals (object o) {\r
87                                 if (o == null || !(o is Key))\r
88                                         return false;\r
89 \r
90                                 Key k = (Key)o;\r
91                                 return options == k.options && pattern.Equals (k.pattern);\r
92                         }\r
93 \r
94                         public override string ToString () {\r
95                                 return "('" + pattern + "', [" + options + "])";\r
96                         }\r
97                 }\r
98         }\r
99 \r
100         class MRUList {\r
101                 public MRUList () {\r
102                         head = tail = null;\r
103                 }\r
104 \r
105                 public void Use (object o) {\r
106                         Node node;\r
107 \r
108                         if (head == null) {\r
109                                 node = new Node (o);\r
110                                 head = tail = node;\r
111                                 return;\r
112                         }\r
113 \r
114                         node = head;\r
115                         while (node != null && !o.Equals (node.value))\r
116                                 node = node.previous;\r
117 \r
118                         if (node == null)\r
119                                 node = new Node (o);\r
120                         else {\r
121                                 if (node == head)\r
122                                         return;\r
123 \r
124                                 if (node == tail)\r
125                                         tail = node.next;\r
126                                 else\r
127                                         node.previous.next = node.next;\r
128 \r
129                                 node.next.previous = node.previous;\r
130                         }\r
131 \r
132                         head.next = node;\r
133                         node.previous = head;\r
134                         node.next = null;\r
135                         head = node;\r
136                 }\r
137 \r
138                 public object Evict () {\r
139                         if (tail == null)\r
140                                 return null;\r
141 \r
142                         object o = tail.value;\r
143                         tail = tail.next;\r
144 \r
145                         if (tail == null)\r
146                                 head = null;\r
147                         else\r
148                                 tail.previous = null;\r
149 \r
150                         return o;\r
151                 }\r
152 \r
153                 private Node head, tail;\r
154 \r
155                 private class Node {\r
156                         public object value;\r
157                         public Node previous, next;\r
158 \r
159                         public Node (object value) {\r
160                                 this.value = value;\r
161                         }\r
162                 }\r
163         }\r
164 }\r