Beispiel #1
0
  @Override
  public final char charAt(int i) {
    if (i < 0 || i >= length()) {
      throw new IndexOutOfBoundsException("Wrong offset: " + i + "; count:" + length());
    }
    i += myStart;
    if (myOriginalSequence != null) return myOriginalSequence.charAt(i);
    final char result;
    if (hasDeferredChanges()) {
      TextChangesStorage storage = myDeferredChangesStorage.get();
      storage.getLock().lock();
      try {
        result = storage.charAt(myArray, i);
      } finally {
        storage.getLock().unlock();
      }
    } else {
      result = myArray[i];
    }

    if (myDebugDeferredProcessing && isDeferredChangeMode()) {
      char expected = myDebugArray.charAt(i);
      if (expected != result) {
        dumpDebugInfo(
            String.format(
                "Incorrect charAt() processing for index %d. Expected: '%c', actual: '%c'",
                i, expected, result));
      }
    }
    return result;
  }
Beispiel #2
0
  public void setText(@Nullable final DocumentImpl subj, final CharSequence chars) {
    myOriginalSequence = chars;
    myArray = null;
    myCount = chars.length();
    myStringRef = null;
    TextChangesStorage storage = myDeferredChangesStorage.get();
    storage.getLock().lock();
    try {
      if (isSubSequence()) {
        myDeferredChangesStorage.set(new TextChangesStorage());
        myStart = 0;
        myEnd = -1;
      } else {
        storage.clear();
      }
    } finally {
      storage.getLock().unlock();
    }

    if (subj != null) {
      trimToSize(subj);
    }

    if (myDebugDeferredProcessing) {
      myDebugArray.setText(subj, chars);
      myDebugDeferredChanges.clear();
    }
  }
Beispiel #3
0
 private void flushDeferredChanged(@NotNull TextChangesStorage storage) {
   storage.getLock().lock();
   try {
     doFlushDeferredChanged();
   } finally {
     storage.getLock().unlock();
   }
 }
Beispiel #4
0
  private void doStoreChange(@NotNull TextChangeImpl change) {
    TextChangesStorage storage = myDeferredChangesStorage.get();
    if (storage.size() >= MAX_DEFERRED_CHANGES_NUMBER) {
      flushDeferredChanged(storage);
    }
    storage.store(change);
    myDeferredShift += change.getDiff();

    if (myDebugDeferredProcessing) {
      myDebugDeferredChanges.add(change);
    }
  }
Beispiel #5
0
 /**
  * Stores given change at collection of deferred changes (merging it with others if necessary) and
  * updates current object state ({@link #length() length} etc).
  *
  * @param change new change to store
  */
 private void storeChange(@NotNull TextChangeImpl change) {
   if (!change.isWithinBounds(length())) {
     LOG.error(
         String.format(
             "Invalid change attempt detected - given change bounds are not within the current char array. Change: %d:%d-%d",
             change.getText().length(), change.getStart(), change.getEnd()),
         dumpState());
     return;
   }
   TextChangesStorage storage = myDeferredChangesStorage.get();
   storage.getLock().lock();
   try {
     doStoreChange(change);
   } finally {
     storage.getLock().unlock();
   }
 }
Beispiel #6
0
  public CharSequence substring(final int start, final int end) {
    if (start == end) return "";
    final CharSequence result;
    if (myOriginalSequence == null) {
      TextChangesStorage storage = myDeferredChangesStorage.get();
      storage.getLock().lock();
      try {
        result = storage.substring(myArray, start + myStart, end + myStart);
      } finally {
        storage.getLock().unlock();
      }
    } else {
      result = myOriginalSequence.subSequence(start, end);
    }

    if (myDebugDeferredProcessing && isDeferredChangeMode()) {
      String expected = myDebugArray.substring(start, end).toString();
      checkStrings(String.format("substring(%d, %d)", start, end), expected, result.toString());
    }
    return result;
  }
Beispiel #7
0
  private void doFlushDeferredChanged() {
    TextChangesStorage storage = myDeferredChangesStorage.get();
    List<TextChangeImpl> changes = storage.getChanges();
    if (changes.isEmpty()) {
      return;
    }

    char[] beforeMerge = null;
    final boolean inPlace;
    if (myDebugDeferredProcessing) {
      beforeMerge = new char[myArray.length];
      System.arraycopy(myArray, 0, beforeMerge, 0, myArray.length);
    }

    BulkChangesMerger changesMerger = BulkChangesMerger.INSTANCE;
    if (myArray.length < length()) {
      myArray = changesMerger.mergeToCharArray(myArray, myCount, changes);
      inPlace = false;
    } else {
      changesMerger.mergeInPlace(myArray, myCount, changes);
      inPlace = true;
    }

    if (myDebugDeferredProcessing) {
      for (int i = 0, max = length(); i < max; i++) {
        if (myArray[i] != myDebugArray.myArray[i]) {
          dumpDebugInfo(
              String.format(
                  "flushDeferredChanged(). Index %d, expected: '%c', actual '%c'. Text before merge: '%s', merge inplace: %b",
                  i, myDebugArray.myArray[i], myArray[i], Arrays.toString(beforeMerge), inPlace));
          break;
        }
      }
    }

    myCount += myDeferredShift;
    myDeferredShift = 0;
    storage.clear();
    myDeferredChangeMode = false;
  }