spellchecker - fast word storage
authorAlexey Gopachenko <alexey.gopachenko@jetbrains.com>
Wed, 25 Aug 2010 11:08:54 +0000 (15:08 +0400)
committerAlexey Gopachenko <alexey.gopachenko@jetbrains.com>
Wed, 25 Aug 2010 11:13:43 +0000 (15:13 +0400)
14 files changed:
plugins/spellchecker/src/com/intellij/spellchecker/compress/Alphabet.java
plugins/spellchecker/src/com/intellij/spellchecker/compress/CompressedDictionary.java
plugins/spellchecker/src/com/intellij/spellchecker/compress/Compressor.java [deleted file]
plugins/spellchecker/src/com/intellij/spellchecker/compress/Encoder.java
plugins/spellchecker/src/com/intellij/spellchecker/compress/UnitBitSet.java
plugins/spellchecker/src/com/intellij/spellchecker/engine/BaseSpellChecker.java
plugins/spellchecker/src/com/intellij/spellchecker/inspections/PlainTextSplitter.java
plugins/spellchecker/src/com/intellij/spellchecker/jetbrains.dic
plugins/spellchecker/testSrc/com/intellij/spellchecker/compress/CompressorTest.java [deleted file]
plugins/spellchecker/testSrc/com/intellij/spellchecker/compress/DictionaryTest.java
plugins/spellchecker/testSrc/com/intellij/spellchecker/compress/EncodeAndCompressTest.java
plugins/spellchecker/testSrc/com/intellij/spellchecker/compress/EncoderTest.java
plugins/spellchecker/testSrc/com/intellij/spellchecker/compress/UnitBitSetTest.java [new file with mode: 0644]
plugins/spellchecker/testSrc/com/intellij/spellchecker/compress/UnitBitSetTests.java [deleted file]

index 65c9aaf4e43a0594e6927c6357e7ae6aa5e8f45b..b7dbcabb024c1f5899b9d0392f87de76f91305f8 100644 (file)
@@ -4,69 +4,65 @@ import org.jetbrains.annotations.NotNull;
 
 public final class Alphabet {
 
-    private final Character[] letters;
-    private int lastIndexUsed = 0;
-    private int maxIndex = 1023;
+  private final char[] letters;
+  private int lastIndexUsed = 0;
+  private static final int MAX_INDEX = UnitBitSet.MAX_UNIT_VALUE;
 
-    public Character getLetter(int position) {
-        assert position < maxIndex;
-        return letters[position];
-    }
+  public char getLetter(int position) {
+    return letters[position];
+  }
 
-    /*
-      @param forceAdd - if set to true - letter will be added to the alphabet if not present yet
-      @return index of the letter or -1 if letter was not found and could not be added (due to forceAdd property value)
-    */
+  /*
+    @param forceAdd - if set to true - letter will be added to the alphabet if not present yet
+    @return index of the letter or -1 if letter was not found and could not be added (due to forceAdd property value)
+  */
 
-    public int getIndex(@NotNull Character letter, boolean forceAdd) {
-        return getNextIndex(0, letter, forceAdd);
-    }
+  public int getIndex(char letter, boolean forceAdd) {
+    final int r = getNextIndex(0, letter, forceAdd);
+    return r;
+  }
 
-    /*
-      @param forceAdd - if set to true - letter will be added to the alphabet if not present yet
-      @return index of the letter or -1 if letter was not found and could not be added (due to forceAdd property value)
-     */
-    public int getNextIndex(int startFrom, @NotNull Character letter, boolean forceAdd) {
-        for (int i = startFrom; i <= lastIndexUsed; i++) {
-            if (letters[i] != null && letters[i].equals(letter)) {
-                return i;
-            }
-        }
-        if (!forceAdd) {
-            return -1;
-        }
-        return add(letter);
+  /*
+   @param forceAdd - if set to true - letter will be added to the alphabet if not present yet
+   @return index of the letter or -1 if letter was not found and could not be added (due to forceAdd property value)
+  */
+  public int getNextIndex(int startFrom, char letter, boolean forceAdd) {
+    for (int i = startFrom; i <= lastIndexUsed; i++) {
+      if (letters[i] != 0 && letters[i] == letter) {
+        return i;
+      }
     }
-
-    public int getLastIndexUsed() {
-        return lastIndexUsed;
+    if (!forceAdd) {
+      return -1;
     }
+    return add(letter);
+  }
 
-    public int getMaxIndex() {
-        return maxIndex;
-    }
+  public int getLastIndexUsed() {
+    return lastIndexUsed;
+  }
 
-    public int add(@NotNull Character c) {
-        lastIndexUsed++;
-        letters[lastIndexUsed] = c;
-        return lastIndexUsed;
-    }
+  public int add(char c) {
+    lastIndexUsed++;
+    letters[lastIndexUsed] = c;
+    return lastIndexUsed;
+  }
 
 
-    Alphabet() {
-        letters = new Character[maxIndex];
-    }
+  Alphabet() {
+    this(MAX_INDEX);
+  }
 
-    Alphabet(int maxIndex) {
-        this.maxIndex = maxIndex;
-        letters = new Character[maxIndex];
-    }
+  Alphabet(int maxIndex) {
+    assert maxIndex <= MAX_INDEX : "alphabet is too long";
+    letters = new char[maxIndex];
+  }
 
-    public static Alphabet create(@NotNull CharSequence alphabet) {
-        Alphabet result = new Alphabet(alphabet.length() + 1);
-        for (int i = 0; i < alphabet.length(); i++) {
-            result.add(alphabet.charAt(i));
-        }
-        return result;
+  // TODO: this should be ONLY way to create it to sped up getIndex
+  Alphabet(@NotNull CharSequence alphabet) {
+    this(alphabet.length() + 1);
+    for (int i = 0; i < alphabet.length(); i++) {
+      add(alphabet.charAt(i));
     }
+  }
 }
index 15020aaffe82877305c0273be26c15ed319d206d..4b3be754dae13475237eb88a745a0815d6eef415 100644 (file)
@@ -33,7 +33,6 @@ public final class CompressedDictionary implements Dictionary {
 
   private final Encoder encoder;
   private final String name;
-  private final Compressor compressor;
 
   private final Map<Integer, SortedSet<byte[]>> rawData = new THashMap<Integer, SortedSet<byte[]>>();
   private static final Comparator<byte[]> COMPARATOR = new Comparator<byte[]>() {
@@ -42,9 +41,8 @@ public final class CompressedDictionary implements Dictionary {
     }
   };
 
-  CompressedDictionary(@NotNull Alphabet alphabet, @NotNull Compressor compressor, @NotNull Encoder encoder, @NotNull String name) {
+  CompressedDictionary(@NotNull Alphabet alphabet, @NotNull Encoder encoder, @NotNull String name) {
     this.alphabet = alphabet;
-    this.compressor = compressor;
     this.encoder = encoder;
     this.name = name;
   }
@@ -86,7 +84,7 @@ public final class CompressedDictionary implements Dictionary {
 
   }
 
-  public List<String> getWords(Character first, int minLength, int maxLength) {
+  public List<String> getWords(char first, int minLength, int maxLength) {
     int index = alphabet.getIndex(first, false);
     List<String> result = new ArrayList<String>();
     if (index == -1) {
@@ -101,7 +99,7 @@ public final class CompressedDictionary implements Dictionary {
         if (toTest[1] != index || toTest[0] > maxLength || toTest[0] < minLength) {
           continue;
         }
-        UnitBitSet set = compressor.decompress(toTest);
+        UnitBitSet set = UnitBitSet.create(toTest);
         result.add(encoder.decode(set));
       }
       i++;
@@ -109,7 +107,7 @@ public final class CompressedDictionary implements Dictionary {
     return result;
   }
 
-  public List<String> getWords(Character first) {
+  public List<String> getWords(char first) {
     return getWords(first, 0, Integer.MAX_VALUE);
   }
 
@@ -123,7 +121,7 @@ public final class CompressedDictionary implements Dictionary {
     }
     try {
       UnitBitSet bs = encoder.encode(word, false);
-      byte[] compressed = compressor.compress(bs);
+      byte[] compressed = UnitBitSet.getBytes(bs);
       int index = -1;
       for (int i = 0; i < lengths.length; i++) {
         if (lengths[i] == compressed.length) {
@@ -175,14 +173,13 @@ public final class CompressedDictionary implements Dictionary {
   public static CompressedDictionary create(@NotNull Loader loader, @NotNull final Transformation transform) {
     Alphabet alphabet = new Alphabet();
     final Encoder encoder = new Encoder(alphabet);
-    final Compressor compressor = new Compressor(2);
-    final CompressedDictionary dictionary = new CompressedDictionary(alphabet, compressor, encoder, loader.getName());
+    final CompressedDictionary dictionary = new CompressedDictionary(alphabet, encoder, loader.getName());
     loader.load(new Consumer<String>() {
       public void consume(String s) {
         String transformed = transform.transform(s);
         if (transformed != null) {
           UnitBitSet bs = encoder.encode(transformed, true);
-          byte[] compressed = compressor.compress(bs);
+          byte[] compressed = UnitBitSet.getBytes(bs);
           dictionary.addToDictionary(compressed);
         }
       }
@@ -195,10 +192,6 @@ public final class CompressedDictionary implements Dictionary {
     if (array1.length != array2.length) {
       return (array1.length < array2.length ? -1 : 1);
     }
-    //array1.length==array2.length
-    if (Arrays.equals(array1, array2)) {
-      return 0;
-    }
     //compare elements values
     for (int i = 0; i < array1.length; i++) {
       if (array1[i] < array2[i]) {
diff --git a/plugins/spellchecker/src/com/intellij/spellchecker/compress/Compressor.java b/plugins/spellchecker/src/com/intellij/spellchecker/compress/Compressor.java
deleted file mode 100644 (file)
index e8e7911..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright 2000-2010 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.spellchecker.compress;
-
-import com.intellij.util.Consumer;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public final class Compressor {
-
-  public static int WORD_LENGTH = 8;
-  public static byte TRANSITION_WORD = new Double(-Math.pow(2, WORD_LENGTH - 1)).byteValue();
-  public final int skipFirst;
-
-  
-  public Compressor(int skipFirst) {
-    this.skipFirst = skipFirst;
-  }
-
-
-  public UnitBitSet decompress(byte[] value) {
-    UnitBitSet bs = new UnitBitSet(WORD_LENGTH - 1, true);
-    int index = 0;
-    int bitsPerUnitInOrigin = value[skipFirst];
-
-    for (int i = skipFirst + 1; i < value.length; i++) {
-      byte b = value[i];
-      if (b > 0) {
-        //decompress verbose word
-        bs.setUnitValue(index++, b);
-      }
-      else {
-        int count = (-TRANSITION_WORD + b);
-        index = index + count + 1;
-      }
-
-    }
-    UnitBitSet result = UnitBitSet.create(bs, bitsPerUnitInOrigin);
-    result.moveRight(skipFirst);
-    for (int i = 0; i < skipFirst; i++) {
-      result.setUnitValue(i, value[i]);
-    }
-
-    return result;
-  }
-
-  public byte[] compress(UnitBitSet origin) {
-    if (origin == null) {
-      return new byte[0];
-    }
-    final List<Byte> words = new ArrayList<Byte>();
-    final List<Byte> compressed = new ArrayList<Byte>();
-
-    final UnitBitSet copyOfOrigin = UnitBitSet.create(origin, origin.bitsPerUnit);
-
-    for (int i = 0; i < skipFirst; i++) {
-      compressed.add(Integer.valueOf(copyOfOrigin.getUnitValue(i)).byteValue());
-    }
-    copyOfOrigin.moveLeft(skipFirst);
-
-    compressed.add(Integer.valueOf(copyOfOrigin.bitsPerUnit).byteValue());
-
-    UnitBitSet bs = UnitBitSet.create(copyOfOrigin, WORD_LENGTH - 1);
-    bs.iterateParUnits(new Consumer<Integer>() {
-
-      public void consume(Integer integer) {
-        if (integer != 0) {
-          //create verbatim word
-          words.add(integer.byteValue());
-        }
-        else {
-          //create transition word
-          words.add(TRANSITION_WORD);
-        }
-
-      }
-    }, 0, true);
-
-
-    int count = -1;
-    for (Byte word : words) {
-      if (word == TRANSITION_WORD && count == -1) {
-        count++;
-      }
-      else if (word == TRANSITION_WORD && count > -1) {
-        count++;
-      }
-      else if (word != TRANSITION_WORD && count > -1) {
-        //compress all transition words
-        while (count > 120) {
-          compressed.add((byte)(TRANSITION_WORD + 120));
-          count -= 121;
-        }
-        if (count > -1) {
-          compressed.add((byte)(TRANSITION_WORD + count));
-        }
-        compressed.add(word);
-        count = -1;
-      }
-      else if (word != TRANSITION_WORD && count == -1) {
-        compressed.add(word);
-        count = -1;
-      }
-    }
-    byte[] result = new byte[compressed.size()];
-    int i = 0;
-    for (Byte word : compressed) {
-      result[i++] = word;
-    }
-    return result;
-  }
-
-
-}
index c00dd7c8841afd7848a8c5d3b091a4370c0d4323..543f3fcc07d9fd92858358a9f10ed1bc39ed6a10 100644 (file)
@@ -1,59 +1,79 @@
 package com.intellij.spellchecker.compress;
 
-import com.intellij.util.Consumer;
 import org.jetbrains.annotations.NotNull;
 
 import java.text.MessageFormat;
 
 public final class Encoder {
 
-    private final Alphabet alphabet;
-    private static final int offset = 2;
+  private final Alphabet alphabet;
+  private static final int offset = 2;
 
-    public Encoder() {
-        alphabet = new Alphabet();
-    }
+  public Encoder() {
+    alphabet = new Alphabet();
+  }
 
-    public Encoder(Alphabet alphabet) {
-        this.alphabet = alphabet;
-    }
+  public Encoder(Alphabet alphabet) {
+    this.alphabet = alphabet;
+  }
+
+  public Alphabet getAlphabet() {
+    return alphabet;
+  }
 
-    public Alphabet getAlphabet() {
-        return alphabet;
+  public UnitBitSet encode(@NotNull CharSequence letters, boolean force) throws EncodingException {
+    assert UnitBitSet.MAX_CHARS_IN_WORD >= letters.length() : "Word is too long ";
+    UnitBitSet bs = new UnitBitSet();
+    for (int i = 0; i < letters.length() - 1 + 1; i++) {
+      char letter = letters.charAt(i);
+      int index = alphabet.getIndex(letter, force);
+      bs.setUnitValue(i + offset, index);
     }
+    bs.setUnitValue(0, letters.length());
+    bs.setUnitValue(1, bs.getUnitValue(2));
+    return bs;
+  }
 
-    public UnitBitSet encode(@NotNull CharSequence letters, boolean force) throws EncodingException {
-        UnitBitSet bs = new UnitBitSet(alphabet.getMaxIndex(), false);
-        for (int i = letters.length() - 1; i >= 0; i--) {
-            Character letter = letters.charAt(i);
-            int index = alphabet.getIndex(letter, force);
-            bs.setUnitValue(i + offset, index);
+  //tested and OK
+  /*
+  public UnitBitSet encodex(@NotNull CharSequence letters, boolean force) throws EncodingException {
+      UnitBitSet bs = new UnitBitSet(alphabet.getMaxIndex(), false);
+      int bitsPerUnit = bs.bitsPerUnit;
+      long[] w = new long[(letters.length() + 2) * bitsPerUnit / Long.SIZE + 1];
+      w[0] |= letters.length();
+      w[0] |= alphabet.getIndex(letters.charAt(0), force) << bitsPerUnit;
+      for (int i = 0; i < letters.length(); i++) {
+        Character letter = letters.charAt(i);
+        int index = alphabet.getIndex(letter, force);
+        int startIndex = (i + offset) * bitsPerUnit;
+        w[startIndex / Long.SIZE] |= ((long)index) << (startIndex % Long.SIZE);
+        if (startIndex % Long.SIZE + bitsPerUnit > Long.SIZE) {
+          w[startIndex / Long.SIZE + 1] |= ((long)index) >>> (Long.SIZE - startIndex % Long.SIZE);
         }
-        bs.setUnitValue(0, letters.length());
-        bs.setUnitValue(1, alphabet.getIndex(letters.charAt(0), force));
-        return bs;
+      }
+      bs.setWords(w);
+      return bs;
     }
+  */
 
-    public String decode(@NotNull UnitBitSet bitSet) throws EncodingException {
-        int wordLength = bitSet.getUnitValue(0);
-        Character firstLetter = alphabet.getLetter(bitSet.getUnitValue(1));
-        final StringBuffer result = new StringBuffer();
-        bitSet.iterateParUnits(new Consumer<Integer>() {
-
-            public void consume(Integer value) {
-                if (value > 0 && value <= alphabet.getLastIndexUsed()) {
-                    result.append(alphabet.getLetter(value));
-                }
-            }
-        }, offset, true);
-
-        final String word = result.toString();
-      final int actualLength = word.length();
-      if (actualLength != wordLength || !word.startsWith(String.valueOf(firstLetter))) {
-            throw new EncodingException(
-                    new MessageFormat("Error during encoding: required length - {0}, starts with {1}, but decoded: {2} ({3})")
-                            .format(new Object[]{wordLength, firstLetter, word, actualLength}));
-        }
-        return word;
+  public String decode(@NotNull UnitBitSet bitSet) throws EncodingException {
+    int wordLength = bitSet.getUnitValue(0);
+    char firstLetter = alphabet.getLetter(bitSet.getUnitValue(1));
+    final StringBuffer result = new StringBuffer();
+    for (int i = 2; i < bitSet.b.length; i++) {
+      int value = bitSet.getUnitValue(i);
+      if (value > 0 && value <= alphabet.getLastIndexUsed()) {
+        result.append(alphabet.getLetter(value));
+      }
+    }
+
+    final String word = result.toString();
+    final int actualLength = word.length();
+    if (actualLength != wordLength || !word.startsWith(String.valueOf(firstLetter))) {
+      throw new EncodingException(
+        new MessageFormat("Error during encoding: required length - {0}, starts with {1}, but decoded: {2} ({3})")
+          .format(new Object[]{wordLength, firstLetter, word, actualLength}));
     }
+    return word;
+  }
 }
\ No newline at end of file
index c8f4ef255da4f13ceead85783c0954ae45d33e59..abd2581066ba9ce59f131f46bb0d728ba508d2d6 100644 (file)
 package com.intellij.spellchecker.compress;
 
-import com.intellij.util.Consumer;
 import org.jetbrains.annotations.NotNull;
 
-import java.util.BitSet;
+import java.util.Arrays;
 
-public class UnitBitSet extends BitSet {
+public class UnitBitSet {
 
-  public int bitsPerUnit = 10;
+  public static final int MAX_CHARS_IN_WORD = 64;
+  public static final int MAX_UNIT_VALUE = 255;
 
-  public UnitBitSet() {
-  }
-
-  public UnitBitSet(int value, boolean exact) {
-    if (exact) {
-      this.bitsPerUnit = value;
-    }
-    else {
-      while (value != 0) {
-        bitsPerUnit++;
-        value >>= 1;
-      }
-    }
-  }
-
-  public void inc() {
-    boolean t = true;
-    for (int i = 0; i <= size(); i++) {
-      if (!get(i) && t) {
-        set(i);
-        t = false;
-      }
-      else if (get(i) && t) {
-        set(i, false);
-      }
-    }
-  }
+  byte[] b = new byte[MAX_CHARS_IN_WORD];
 
   public int getUnitValue(int number) {
-    int startIndex = number * bitsPerUnit;
-    int result = 0;
-    for (int i = 0; i < bitsPerUnit; i++) {
-      if (get(startIndex + i)) {
-        result += (1 << i);
-      }
-    }
-    return result;
+    final int r = b[number] & 0xFF;
+    assert r >= 0 && r <= MAX_UNIT_VALUE : "invalid unit value";
+    return r;
   }
 
   public void setUnitValue(int number, int value) {
-    if (value > (1 << bitsPerUnit)  - 1) {
-      throw new IllegalArgumentException();
-    }
-    int startIndex = number * bitsPerUnit;
-    for (int i = 0; i < bitsPerUnit; i++) {
-      set(startIndex + i, value % 2 == 1);
-      value /= 2;
-    }
+    //assert value >= 0 : "unit value is negative" + value;
+    assert value <= MAX_UNIT_VALUE : "unit value is too big";
+    b[number] = (byte)value;
   }
 
-  public void setBits(int... bits) {
-    if (bits == null) {
-      return;
-    }
-    for (int bit : bits) {
-      set(bit);
-    }
+  @Override
+  public boolean equals(Object obj) {
+    if (!(obj instanceof UnitBitSet)) return false;
+    return Arrays.equals(b, ((UnitBitSet)obj).b);
   }
 
-  public void moveLeft(int n) {
-    if (n <= 0) {
-      return;
-    }
-    for (int i = 0; i < size() - n * bitsPerUnit; i++) {
-      set(i, get(n * bitsPerUnit + i));
-    }
-    for (int i = size() - n * bitsPerUnit; i < size(); i++) {
-      set(i, false);
+  @Override
+  public String toString() {
+    final StringBuilder s = new StringBuilder();
+    for (int i = 0; i < b.length; i++) {
+      s.append(Integer.toHexString((int)b[i] & 0xFF));
     }
+    return s.toString();
   }
 
-  public void moveRight(int n) {
-    if (n <= 0) {
-      return;
-    }
-    for (int i = size() - 1; i >= 0; i--) {
-      set(i + n * bitsPerUnit, get(i));
-    }
-    for (int i = 0; i < n * bitsPerUnit; i++) {
-      set(i, false);
-    }
+  public static UnitBitSet create(@NotNull UnitBitSet origin) {
+    UnitBitSet r = new UnitBitSet();
+    System.arraycopy(origin.b, 0, r.b, 0, r.b.length);
+    return r;
   }
 
-
-  public void iterateParUnits(@NotNull Consumer<Integer> consumer, int offset, boolean skipLastZero) {
-    int units = size() / bitsPerUnit;
-    for (int i = offset; i <= units; i++) {
-      consumer.consume(getUnitValue(i));
-      if (skipLastZero && nextSetBit(i) == -1) {
-        break;
-      }
-    }
+  public static UnitBitSet create(byte[] value) {
+    final UnitBitSet r = new UnitBitSet();
+    System.arraycopy(value, 0, r.b, 0, value.length);
+    return r;
   }
 
-  public static UnitBitSet create(int... bits) {
-    UnitBitSet bs = new UnitBitSet();
-    bs.setBits(bits);
-    return bs;
-  }
 
-  public static UnitBitSet create(int bitsPerUnit, boolean exact, int... bits) {
-    UnitBitSet bs = new UnitBitSet(bitsPerUnit, exact);
-    bs.setBits(bits);
-    return bs;
+  static public byte[] getBytes(UnitBitSet origin) {
+    final byte[] r = new byte[origin.b[0] + 2];
+    System.arraycopy(origin.b, 0, r, 0, r.length);
+    return r;
   }
 
-  public static UnitBitSet create(@NotNull BitSet bitSet, int bitsPerUnit) {
-    UnitBitSet result = new UnitBitSet(bitsPerUnit, true);
-    result.or(bitSet);
-    return result;
-  }
 }
index 51d0929d8cfb73faa3156dc42ee595d69df9373f..0070ba9313254294866a6813ac021177ed3afb02 100644 (file)
@@ -90,7 +90,7 @@ public class BaseSpellChecker implements SpellCheckerEngine {
   }
 
   @NotNull
-  private static List<String> restore(@NotNull Character startFrom, int i, int j, @Nullable Collection dictionaries) {
+  private static List<String> restore(char startFrom, int i, int j, @Nullable Collection dictionaries) {
     if (dictionaries == null) {
       return Collections.emptyList();
     }
@@ -106,7 +106,7 @@ public class BaseSpellChecker implements SpellCheckerEngine {
   }
 
   @NotNull
-  private static List<String> restore(@NotNull final Character first, final int i, final int j, @Nullable Dictionary dictionary) {
+  private static List<String> restore(final char first, final int i, final int j, @Nullable Dictionary dictionary) {
     if (dictionary == null) {
       return Collections.emptyList();
     }
index 9435f63f05cbe4aa93a093cf04edade80c64a5b0..4a5ec122106a4b081dfee02ce8679b8343728761 100644 (file)
@@ -23,6 +23,7 @@ import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.regex.Pattern;
 
@@ -30,8 +31,12 @@ public class PlainTextSplitter extends BaseSplitter {
 
 
   @NonNls
-  private static final Pattern COMPLEX =
-    Pattern.compile("([\\p{L}0-9\\.\\-\\_]+@([\\p{L}0-9\\-\\_]+\\.)+(com|net|[a-z]{2}))|((ftp|http|file|https)://([^/]+)(/.*)?(/.*))");
+  private static final Pattern MAIL =
+    Pattern.compile("([\\p{L}0-9\\.\\-\\_]+@([\\p{L}0-9\\-\\_]+\\.)+(com|net|[a-z]{2}))");
+
+  @NonNls
+  private static final Pattern URL =
+    Pattern.compile("((ftp|http|file|https)://([^/]+)(/.*)?(/.*))");
 
 
   public List<CheckArea> split(@Nullable String text, @NotNull TextRange range) {
@@ -42,7 +47,18 @@ public class PlainTextSplitter extends BaseSplitter {
       return null;
     }
 
-    List<TextRange> toCheck = excludeByPattern(text, range, COMPLEX, 0);
+    List<TextRange> toCheck;
+    if (text.indexOf('@')>0) {
+      toCheck = excludeByPattern(text, range, MAIL, 0);
+    }
+    else
+    if (text.indexOf(':')>0) {
+      toCheck = excludeByPattern(text, range, URL, 0);
+    }
+    else
+    {
+      toCheck = Collections.singletonList(range);
+    }
 
     if (toCheck == null) return null;
 
index 2a72bf73674cca36366691baea3f6dfb32f1ac80..4d412306660b0a1da61555b44febbc053e748cee 100644 (file)
@@ -63,8 +63,6 @@ filename
 fileset
 filesets
 filesystem
-float4
-float8
 foreach
 formatter
 freelist
@@ -283,7 +281,6 @@ whitespace
 wildcard
 workflow
 wsdl
-x509
 xmlschema
 xmlschemas
 xmltype
diff --git a/plugins/spellchecker/testSrc/com/intellij/spellchecker/compress/CompressorTest.java b/plugins/spellchecker/testSrc/com/intellij/spellchecker/compress/CompressorTest.java
deleted file mode 100644 (file)
index 556cf31..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright 2000-2010 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.spellchecker.compress;
-
-import junit.framework.TestCase;
-
-import java.util.Random;
-
-public class CompressorTest extends TestCase {
-
-    public void testCompressorWithDefinedData() {
-        Compressor compressor = new Compressor(0);
-        UnitBitSet bs = UnitBitSet.create(1, 3, 5, 10);
-        final byte[] compressed = compressor.compress(bs);
-        assertEquals(3, compressed.length);
-        assertEquals(42, compressed[1]);
-        assertEquals(8, compressed[2]);
-        final UnitBitSet restored = compressor.decompress(compressed);
-        assertEquals(bs, restored);
-    }
-
-    public void testCompressorWithRandomData() {
-        Compressor compressor = new Compressor(0);
-        int max = 10;
-        for (int i = 0; i < 1000; i++) {
-            int[] values = getRandoms(1000, max);
-            final UnitBitSet bitSet = new UnitBitSet();
-            for (int value : values) {
-                bitSet.set(value);
-            }
-            final byte[] compressed = compressor.compress(bitSet);
-            final UnitBitSet decompressed = compressor.decompress(compressed);
-            boolean check = (bitSet.equals(decompressed));
-            if (!check) {
-                System.out.println("bitSet: " + bitSet);
-                System.out.println("decompressed: " + decompressed);
-                compressor.compress(bitSet);
-                compressor.decompress(compressed);
-            }
-            assertEquals(bitSet, decompressed);
-        }
-    }
-
-    private static int[] getRandoms(int max, int count) {
-        int[] result = new int[count];
-        for (int i = 0; i < count; i++) {
-            result[i] = new Random().nextInt(max);
-        }
-        return result;
-    }
-
-}
index 76140ca556242cefa4870ffa8148787f5a6e9ccf..b60e36cd77eaa6e0114cbf90dd10600773cb6851 100644 (file)
@@ -48,8 +48,8 @@ public class DictionaryTest extends TestCase {
   }
 
   {
-    times.put(JETBRAINS_DIC, 100);
-    times.put(ENGLISH_DIC, 5000);
+    times.put(JETBRAINS_DIC, 1000);
+    times.put(ENGLISH_DIC, 50000);
   }
 
   public void testDictionary() throws IOException {
@@ -131,7 +131,7 @@ public class DictionaryTest extends TestCase {
     CompressedDictionary dictionary = CompressedDictionary.create(loader, new Transformation());
     for (String s : sets.getSecond()) {
       if (!sets.getFirst().contains(s)) {
-        assertFalse(dictionary.contains(s));
+        assertFalse(s, dictionary.contains(s));
       }
     }
   }
index 37082acc133b72c1f56c9773f98818f4b8d32557..c43aa54d7432e7978ca77922bd203d133228ddab 100644 (file)
@@ -1,8 +1,5 @@
 package com.intellij.spellchecker.compress;
 
-import com.intellij.spellchecker.compress.Compressor;
-import com.intellij.spellchecker.compress.Encoder;
-import com.intellij.spellchecker.compress.UnitBitSet;
 import junit.framework.TestCase;
 
 
@@ -10,11 +7,10 @@ public class EncodeAndCompressTest extends TestCase {
 
     public void testEncodeAndCompress() {
         Encoder encoder = new Encoder();
-        Compressor compressor = new Compressor(2);
         String word = "example";
         UnitBitSet bs = encoder.encode(word, true);
-        byte[] compressed = compressor.compress(bs);
-        final UnitBitSet decompressed = compressor.decompress(compressed);
+        byte[] compressed = UnitBitSet.getBytes(bs);
+        final UnitBitSet decompressed = UnitBitSet.create(compressed);
         assertEquals(bs,decompressed);
         String restored = encoder.decode(decompressed);
         assertEquals(word,restored);
index 23bff92b5494f767d90f850632afc91205246415..67938d4538571502e9901a232f3acb1c02055214 100644 (file)
@@ -15,9 +15,6 @@
  */
 package com.intellij.spellchecker.compress;
 
-import com.intellij.spellchecker.compress.Alphabet;
-import com.intellij.spellchecker.compress.Encoder;
-import com.intellij.spellchecker.compress.UnitBitSet;
 import junit.framework.TestCase;
 
 public class EncoderTest extends TestCase {
@@ -93,7 +90,7 @@ public class EncoderTest extends TestCase {
 
 
     public void testWithPredefinedAlphabet() {
-        Encoder encoder = new Encoder(Alphabet.create("abcdefghijklmnopqrst"));
+        Encoder encoder = new Encoder(new Alphabet("abcdefghijklmnopqrst"));
         final String wordToTest1 = "asia";
         //letter 'a' will be added at the end
         final UnitBitSet bitSet = encoder.encode(wordToTest1, true);
diff --git a/plugins/spellchecker/testSrc/com/intellij/spellchecker/compress/UnitBitSetTest.java b/plugins/spellchecker/testSrc/com/intellij/spellchecker/compress/UnitBitSetTest.java
new file mode 100644 (file)
index 0000000..dbf7169
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.spellchecker.compress;
+
+import junit.framework.TestCase;
+
+import java.util.Random;
+
+public class UnitBitSetTest extends TestCase {
+
+  public void testUnitValue() {
+    int bitsPerUnit = 256;
+    for (int i = 0; i < bitsPerUnit - 1; i++) {
+      UnitBitSet bs = new UnitBitSet();
+      bs.setUnitValue(0, i);
+      assertEquals(i, bs.getUnitValue(0));
+      assertEquals(0, bs.getUnitValue(1));
+    }
+  }
+
+  public void testCreateFromBitSet() {
+    UnitBitSet bs1 = new UnitBitSet();
+    bs1.setUnitValue(5, 255);
+    UnitBitSet bs2 = UnitBitSet.create(bs1);
+    assertEquals(bs2, bs1);
+  }
+
+  public void testCompressorWithRandomData() {
+    int amount = 10;
+    for (int i = 0; i < 1000; i++) {
+      int[] values = getRandoms(UnitBitSet.MAX_UNIT_VALUE, amount);
+      final UnitBitSet bitSet = new UnitBitSet();
+      bitSet.setUnitValue(0, values.length);
+      for (int i1 = 1, valuesLength = values.length; i1 < valuesLength; i1++) {
+        int value = values[i1];
+        bitSet.setUnitValue(i1, value);
+      }
+      final byte[] compressed = UnitBitSet.getBytes(bitSet);
+      final UnitBitSet decompressed = UnitBitSet.create(compressed);
+      boolean check = (bitSet.equals(decompressed));
+      if (!check) {
+        System.out.println("bitSet: " + bitSet);
+        System.out.println("decompressed: " + decompressed);
+        UnitBitSet.getBytes(bitSet);
+        UnitBitSet.create(compressed);
+      }
+      assertEquals(bitSet, decompressed);
+    }
+  }
+
+  private static int[] getRandoms(int max, int count) {
+    int[] result = new int[count];
+    for (int i = 0; i < count; i++) {
+      result[i] = new Random().nextInt(max);
+    }
+    return result;
+  }
+
+}
diff --git a/plugins/spellchecker/testSrc/com/intellij/spellchecker/compress/UnitBitSetTests.java b/plugins/spellchecker/testSrc/com/intellij/spellchecker/compress/UnitBitSetTests.java
deleted file mode 100644 (file)
index 6b7e3b7..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-package com.intellij.spellchecker.compress;
-
-import junit.framework.TestCase;
-
-public class UnitBitSetTests extends TestCase {
-
-    public void testUnitValue() {
-        int bitsPerUnit = 256;
-        for (int i = 0; i < bitsPerUnit-1; i++) {
-            UnitBitSet bs = UnitBitSet.create(bitsPerUnit);
-            bs.setUnitValue(0, i);
-            assertEquals(i, bs.getUnitValue(0));
-            assertEquals(0, bs.getUnitValue(1));
-        }
-    }
-
-     public void testCreateFromBitSet() {
-        UnitBitSet bs1 = UnitBitSet.create(1,5,10);
-        UnitBitSet bs2 = UnitBitSet.create(bs1,7);
-        assertEquals(bs2,bs1); 
-    }
-
-     public void testMoveLeft() {
-        UnitBitSet bs1 = UnitBitSet.create(3,true, 1,3,5,10);
-        bs1.moveLeft(2);
-        assertEquals(UnitBitSet.create(3,true,4),bs1); 
-    }
-
-     public void testMoveLeft2() {
-        UnitBitSet bs1 = UnitBitSet.create(10,true, 1,3,5,10);
-        bs1.moveLeft(2);
-        assertEquals(UnitBitSet.create(10,true),bs1); 
-    }
-
-     public void testMoveRight() {
-        UnitBitSet bs1 = UnitBitSet.create(3,true, 1,3,5,10);
-        bs1.moveRight(2);
-        assertEquals(UnitBitSet.create(3,true,7,9,11,16),bs1); 
-    }
-
-
-
-}