2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
19 namespace Mono.Lucene.Net.Analysis
23 /// <summary> A simple class that stores Strings as char[]'s in a
24 /// hash table. Note that this is not a general purpose
25 /// class. For example, it cannot remove items from the
26 /// set, nor does it resize its hash table to be smaller,
27 /// etc. It is designed to be quick to test if a char[]
28 /// is in the set without the necessity of converting it
29 /// to a String first.
32 public class CharArraySet:System.Collections.Hashtable
34 public override int Count
42 private const int INIT_SIZE = 8;
43 private char[][] entries;
45 private bool ignoreCase;
47 /// <summary>Create set with enough capacity to hold startSize
50 public CharArraySet(int startSize, bool ignoreCase)
52 this.ignoreCase = ignoreCase;
54 while (startSize + (startSize >> 2) > size)
56 entries = new char[size][];
59 /// <summary>Create set from a Collection of char[] or String </summary>
60 public CharArraySet(System.Collections.ICollection c, bool ignoreCase):this(c.Count, ignoreCase)
62 System.Collections.IEnumerator e = c is CharArraySet ? ((CharArraySet)c).GetEnumerator() : c.GetEnumerator();
68 /// <summary>Create set from entries </summary>
69 private CharArraySet(char[][] entries, bool ignoreCase, int count)
71 this.entries = entries;
72 this.ignoreCase = ignoreCase;
76 /// <summary>true if the <code>len</code> chars of <code>text</code> starting at <code>off</code>
79 public virtual bool Contains(char[] text, int off, int len)
81 return entries[GetSlot(text, off, len)] != null;
84 /// <summary>true if the <code>System.String</code> is in the set </summary>
85 public virtual bool Contains(System.String cs)
87 return entries[GetSlot(cs)] != null;
90 private int GetSlot(char[] text, int off, int len)
92 int code = GetHashCode(text, off, len);
93 int pos = code & (entries.Length - 1);
94 char[] text2 = entries[pos];
95 if (text2 != null && !Equals(text, off, len, text2))
97 int inc = ((code >> 8) + code) | 1;
101 pos = code & (entries.Length - 1);
102 text2 = entries[pos];
104 while (text2 != null && !Equals(text, off, len, text2));
109 /// <summary>Returns true if the String is in the set </summary>
110 private int GetSlot(System.String text)
112 int code = GetHashCode(text);
113 int pos = code & (entries.Length - 1);
114 char[] text2 = entries[pos];
115 if (text2 != null && !Equals(text, text2))
117 int inc = ((code >> 8) + code) | 1;
121 pos = code & (entries.Length - 1);
122 text2 = entries[pos];
124 while (text2 != null && !Equals(text, text2));
129 /// <summary>Add this String into the set </summary>
130 public virtual bool Add(System.String text)
132 return Add(text.ToCharArray());
135 /// <summary>Add this char[] directly to the set.
136 /// If ignoreCase is true for this Set, the text array will be directly modified.
137 /// The user should never modify this text array after calling this method.
139 public virtual bool Add(char[] text)
142 for (int i = 0; i < text.Length; i++)
143 text[i] = System.Char.ToLower(text[i]);
144 int slot = GetSlot(text, 0, text.Length);
145 if (entries[slot] != null)
147 entries[slot] = text;
150 if (count + (count >> 2) > entries.Length)
158 private bool Equals(char[] text1, int off, int len, char[] text2)
160 if (len != text2.Length)
164 for (int i = 0; i < len; i++)
166 if (System.Char.ToLower(text1[off + i]) != text2[i])
172 for (int i = 0; i < len; i++)
174 if (text1[off + i] != text2[i])
181 private bool Equals(System.String text1, char[] text2)
183 int len = text1.Length;
184 if (len != text2.Length)
188 for (int i = 0; i < len; i++)
190 if (System.Char.ToLower(text1[i]) != text2[i])
196 for (int i = 0; i < len; i++)
198 if (text1[i] != text2[i])
205 private void Rehash()
207 int newSize = 2 * entries.Length;
208 char[][] oldEntries = entries;
209 entries = new char[newSize][];
211 for (int i = 0; i < oldEntries.Length; i++)
213 char[] text = oldEntries[i];
216 // todo: could be faster... no need to compare strings on collision
217 entries[GetSlot(text, 0, text.Length)] = text;
222 private int GetHashCode(char[] text, int offset, int len)
225 int stop = offset + len;
228 for (int i = offset; i < stop; i++)
230 code = code * 31 + System.Char.ToLower(text[i]);
235 for (int i = offset; i < stop; i++)
237 code = code * 31 + text[i];
243 private int GetHashCode(System.String text)
246 int len = text.Length;
249 for (int i = 0; i < len; i++)
251 code = code * 31 + System.Char.ToLower(text[i]);
256 for (int i = 0; i < len; i++)
258 code = code * 31 + text[i];
264 public virtual int Size()
269 public virtual bool IsEmpty()
274 public override bool Contains(System.Object o)
278 char[] text = (char[]) o;
279 return Contains(text, 0, text.Length);
281 return Contains(o.ToString());
284 //LUCENENET-414 (https://issues.apache.org/jira/browse/LUCENENET-414)
285 public virtual bool Add(object key, object value)
290 public virtual bool Add(System.Object o)
294 return Add((char[]) o);
297 if (o is System.Collections.Hashtable)
299 foreach (string word in ((System.Collections.Hashtable)o).Keys)
306 return Add(o.ToString());
309 /// <summary> Returns an unmodifiable {@link CharArraySet}. This allows to provide
310 /// unmodifiable views of internal sets for "read-only" use.
313 /// <param name="set">a set for which the unmodifiable set is returned.
315 /// <returns> an new unmodifiable {@link CharArraySet}.
317 /// <throws> NullPointerException </throws>
318 /// <summary> if the given set is <code>null</code>.
320 public static CharArraySet UnmodifiableSet(CharArraySet set_Renamed)
322 if (set_Renamed == null)
323 throw new System.NullReferenceException("Given set is null");
325 * Instead of delegating calls to the given set copy the low-level values to
326 * the unmodifiable Subclass
328 return new UnmodifiableCharArraySet(set_Renamed.entries, set_Renamed.ignoreCase, set_Renamed.count);
331 /// <summary>The Iterator<String> for this set. Strings are constructed on the fly, so
332 /// use <code>nextCharArray</code> for more efficient access.
334 public class CharArraySetIterator : System.Collections.IEnumerator
336 private void InitBlock(CharArraySet enclosingInstance)
338 this.enclosingInstance = enclosingInstance;
340 private CharArraySet enclosingInstance;
341 /// <summary>Returns the next String, as a Set<String> would...
342 /// use nextCharArray() for better efficiency.
344 public virtual System.Object Current
348 return new System.String(NextCharArray());
352 public CharArraySet Enclosing_Instance
356 return enclosingInstance;
360 internal int pos = - 1;
361 internal char[] next_Renamed_Field;
362 internal CharArraySetIterator(CharArraySet enclosingInstance)
364 InitBlock(enclosingInstance);
368 private void GoNext()
370 next_Renamed_Field = null;
372 while (pos < Enclosing_Instance.entries.Length && (next_Renamed_Field = Enclosing_Instance.entries[pos]) == null)
376 public virtual bool MoveNext()
378 return next_Renamed_Field != null;
381 /// <summary>do not modify the returned char[] </summary>
382 public virtual char[] NextCharArray()
384 char[] ret = next_Renamed_Field;
389 public virtual void Remove()
391 throw new System.NotSupportedException();
394 virtual public void Reset()
396 System.Diagnostics.Debug.Fail("Port issue:", "Need to implement this call, CharArraySetIterator.Reset()"); // {{Aroush-2.9
401 public new System.Collections.IEnumerator GetEnumerator()
403 return new CharArraySetIterator(this);
406 /// <summary> Efficient unmodifiable {@link CharArraySet}. This implementation does not
407 /// delegate calls to a give {@link CharArraySet} like
408 /// {@link Collections#UnmodifiableSet(java.util.Set)} does. Instead is passes
409 /// the internal representation of a {@link CharArraySet} to a super
410 /// constructor and overrides all mutators.
412 private sealed class UnmodifiableCharArraySet:CharArraySet
415 internal UnmodifiableCharArraySet(char[][] entries, bool ignoreCase, int count):base(entries, ignoreCase, count)
419 public override bool Add(System.Object o)
421 throw new System.NotSupportedException();
424 public override bool AddAll(System.Collections.ICollection coll)
426 throw new System.NotSupportedException();
429 public override bool Add(char[] text)
431 throw new System.NotSupportedException();
434 public override bool Add(System.String text)
436 throw new System.NotSupportedException();
440 /// <summary>Adds all of the elements in the specified collection to this collection </summary>
441 public virtual bool AddAll(System.Collections.ICollection items)
444 System.Collections.IEnumerator iter = items.GetEnumerator();
446 while (iter.MoveNext())
454 /// <summary>Removes all elements from the set </summary>
455 public virtual new bool Clear()
457 throw new System.NotSupportedException();
460 /// <summary>Removes from this set all of its elements that are contained in the specified collection </summary>
461 public virtual bool RemoveAll(System.Collections.ICollection items)
463 throw new System.NotSupportedException();
466 /// <summary>Retains only the elements in this set that are contained in the specified collection </summary>
467 public bool RetainAll(System.Collections.ICollection coll)
469 throw new System.NotSupportedException();