/** * Inserts a new record. * * @param pre record PRE * @param id record ID * @param c number of inserted records */ public void insert(final int pre, final int id, final int c) { if (rows == 0 && pre == id && id == baseid + 1) { // no mapping and we append at the end => nothing to do baseid += c; return; } int pos = 0; int inc = c; int oid = pre; if (rows > 0) { pos = Arrays.binarySearch(pres, 0, rows, pre); if (pos < 0) { pos = -pos - 1; if (pos != 0) { // check if inserting into an existing id interval final int prev = pos - 1; final int prevcnt = nids[prev] - fids[prev] + 1; final int prevpre = pres[prev]; if (pre < prevpre + prevcnt) { // split the id interval final int split = pre - prevpre; final int fid = fids[prev] + split; // add a new next interval add(pos, pre, fid, nids[prev], incs[prev], oids[prev]); // shrink the previous interval nids[prev] = fid - 1; incs[prev] -= prevcnt - split; oid = oids[prev]; inc += incs[prev]; } else { oid = pre - incs[prev]; inc += incs[prev]; } } } else if (pos > 0) { oid = oids[pos]; inc += incs[pos - 1]; } increment(pos, c); } // add the new interval add(pos, pre, id, id + c - 1, inc, oid); }
/** * Deletes records. * * @param pre PRE of the first record * @param id ID of the first deleted record * @param c number of deleted records (negative) */ public void delete(final int pre, final int id, final int c) { if (rows == 0 && pre == id && id - c == baseid + 1) { // no mapping and we delete at the end => nothing to do baseid += c; return; } if (rows == 0) { // no previous updates: add a new record add(0, pre, INV, INV, c, id); return; } final int end = pre - c - 1; final int startIndex = findPre(pre); // remove all updates which has affected records which now have to be deleted final int removeStart = startIndex < rows && pres[startIndex] < pre ? startIndex + 1 : startIndex; int removeEnd = -1; for (int i = startIndex; i < rows; ++i) { if (end < pres[i] + nids[i] - fids[i]) break; removeEnd = i; } final int inc; final int oid; int endIndex; if (removeEnd >= 0) { inc = incs[removeEnd]; oid = oids[removeEnd]; endIndex = removeStart; remove(removeStart, removeEnd); } else { inc = startIndex > 0 ? incs[startIndex - 1] : 0; oid = id; endIndex = startIndex; } if (rows <= startIndex) { // the delete does not affect previous updates add(startIndex, pre, INV, INV, inc + c, oid); return; } final int min = pres[startIndex]; if (startIndex < endIndex) { if (endIndex < rows && pres[endIndex] <= end) { shrinkFromStart(endIndex, pre, c); shrinkFromEnd(startIndex, pre, inc + c); } else { --endIndex; // endIndex is not processed, so we let the increment do that shrinkFromEnd(startIndex, pre, inc + c); } } else if (min < pre) { add( ++endIndex, pres[startIndex], fids[startIndex], nids[startIndex], incs[startIndex], oids[startIndex]); shrinkFromStart(endIndex, pre, c); shrinkFromEnd(startIndex, pre, inc + c); } else if (end < min) { add(endIndex, pre, INV, INV, inc + c, oid); } else { shrinkFromStart(startIndex, pre, c); } increment(endIndex + 1, c); }