📄 recordenumerationimpl.java
字号:
synchronized (recordStore.rsLock) { filterAdd(recordId); } } /** * From the RecordListener interface. This method is called when a * record in <code>recordStore</code> is deleted. * * @param recordStore the record store from which a record was deleted * @param recordId the record id of the deleted record */ public synchronized void recordDeleted(RecordStore recordStore, int recordId) { checkDestroyed(); /* * Remove the deleted element from the records array. * No resorting is required. */ int recIndex = findIndexOfRecord(recordId); if (recIndex < 0) return; // not in the enumeration // remove this record from the enumeration removeRecordAtIndex(recIndex); } /** * Implements RecordEnumeration.destroy() interface. Called * to signal that this enumeration will no longer be used, and that * its resources may be collected. */ public synchronized void destroy() { checkDestroyed(); if (beObserver == true) { recordStore.removeRecordListener(this); } filter = null; comparator = null; records = null; recordStore = null; // a signal that this is destroyed! } /** * Helper method that checks if this enumeration can be used. * If this enumeration has been destroyed, an exception is thrown. * * @exception IllegalStateException if RecordEnumeration has been * destroyed. */ private void checkDestroyed() { if (recordStore == null) throw new IllegalStateException(); } /** * Used to add a record to an already filtered and sorted * <code>records</code> array. More efficient than * <code>reFilterSort</code> because it relys on * <code>records</code> being in sorted order. * * First ensures that record <code>recordId</code> * meets this enumeration's filter criteria. * If it does it is added to records as array element * 0. If a comparator is defined for this enumeration, * the helper method <code>sortAdd</code> is called to * properly position <code>recordId</code> within the ordered * <code>records</code> array. * * Should be called from within a * synchronized (recordStore.rsLock) block. * * @param recordId the record to add to this enumeration */ private void filterAdd(int recordId) { int insertPoint = -1; if (filter != null) { try { if (!filter.matches(recordStore.getRecord(recordId))) return; // recordId filtered out } catch (RecordStoreException rse) { return; // recordId does not exist } } // the new record has been accepted by the filter int[] newrecs = new int[records.length + 1]; newrecs[0] = recordId; // insert new record at front of list System.arraycopy(records, 0, newrecs, 1, records.length); records = newrecs; if (comparator != null) { // move the new record into place try { insertPoint = sortInsert(); } catch (RecordStoreException rse) { // NOTE: - should never be here // throw a RSE? destroy record enumeration? System.out.println("Unexpected exception in filterAdd"); } } // keep index up to date as well if (index != NO_SUCH_RECORD && insertPoint != -1 && insertPoint < index) { index++; } } /** * Helper method called by <code>filterAdd</code>. * Moves the posibly unsorted element zero in the * <code>records</code> array to its sorted position * within the array. * * @return index of inserted element. * @exception RecordStoreException if an error occurs * in the comparator function. */ private int sortInsert() throws RecordStoreException { // bubble sort the first record in records into place int tmp; int i; int j; for (i = 0, j = 1; i < records.length - 1; i++, j++) { if (comparator.compare(recordStore.getRecord(records[i]), recordStore.getRecord(records[j])) == RecordComparator.FOLLOWS) { // if i follows j swap them in records tmp = records[i]; records[i] = records[j]; records[j] = tmp; } else { break; // done sorting if compare returns EQUALS or PRECEDES } } return i; // final index of new record in records } /** * Find the index in records of record <code>recordId</code> * and return it. * * @param recordId the record index to find * @return the index of the record, or -1. */ private int findIndexOfRecord(int recordId) { int idx; int recIndex = -1; for (idx = records.length - 1; idx >= 0; idx--) { if (records[idx] == recordId) { recIndex = idx; break; } } return recIndex; } /** * Internal helper method which * removes the array element at index <code>recIndex</code> * from the internal <code>records</code> array. * * <code>recIndex</code> should be non negative. * * @param recIndex the array element to remove. */ private void removeRecordAtIndex(int recIndex) { int[] tmp = new int[records.length - 1]; if (recIndex < records.length) { System.arraycopy(records, 0, tmp, 0, recIndex); System.arraycopy(records, recIndex + 1, tmp, recIndex, (records.length - recIndex) - 1); } else { System.arraycopy(records, 0, tmp, 0, records.length - 1); } records = tmp; /* * If a record prior to current index was deleted * update index so nothing is skipped */ if (index != NO_SUCH_RECORD && recIndex < index) { index --; } else if (index == records.length) { // last element in records removed index --; } } /** * Internal helper method for filtering and sorting records if * necessary. Called from rebuild(). * * Should be called from within a synchronized(recordStore.rsLock) block * * @param filtered array of record stores to filter and sort. */ private void reFilterSort(int[] filtered) { int filteredIndex = 0; if (filter == null) { /* * If this enumeration doesn't have any filters, the * recordId's returned by getRecordIDs should be * used as they are. */ records = filtered; } else { /* * If a filter has been specified, filter the recordStore * records to determine the subset to be used for this * enumeration. */ for (int i = 0; i < filtered.length; i++) { // if this record matches the filter keep it try { if (filter.matches(recordStore.getRecord(filtered[i]))) { // not sure if element overlap is allowed if (filteredIndex != i) { filtered[filteredIndex++] = filtered[i]; } else { filteredIndex++; } } } catch (RecordStoreException rse) { // if a record can't be found it doesn't match } } records = new int[filteredIndex]; System.arraycopy(filtered, 0, records, 0, filteredIndex); } /* * If a comparator has been specified, sort the remaining * records by comparing records against each other using * the comparator the application provides. */ if (comparator != null) { try { QuickSort(records, 0, records.length - 1, comparator); } catch (RecordStoreException de) { // NOTE: - should never be here // throw a RSE? destroy record enumeration? System.out.println("Unexpected exception in " + "reFilterSort"); } } reset(); // reset the current index of this enumeration } /** * Quicksort helper function for sorting the records. * * @param a the array of recordId's to sort using comparator. * @param lowIndex the low bound of the range to sort. * @param highIndex the hight bound of the range to sort. * @param comparator the RecordComparator to use to compare records. */ private void QuickSort(int a[], int lowIndex, int highIndex, RecordComparator comparator) throws RecordStoreException { /* * A different sorting algorithm may be preferred, because a * large recursive quicksort can consume lots of * stack. Quicksort is very fast for most random sequences * however... */ int left = lowIndex; // the "left" index int right = highIndex; // the "right" index /* * First partition the data into two regions, where every * element on the left side of the partition is less than * every element on the right side of the element. */ if (highIndex > lowIndex) { /* * Arbitrarily choose the initial pivot point to be the * middle of the array. */ int ind = (lowIndex + highIndex) / 2; int pivotIndex = a[ind]; byte[] pivotData = recordStore.getRecord(pivotIndex); // loop through the array until the indices cross while (left <= right) { /* * Starting on the left, scan right until the * first element greater than or equal to the * pivot element is found. */ while ((left < highIndex) && (comparator.compare(recordStore.getRecord(a[left]), pivotData) == RecordComparator.PRECEDES)) { left++; } /* * Starting on the right, scan left until the * first element that is less than or equal to the * pivot element is found. */ while ((right > lowIndex) && (comparator.compare(recordStore.getRecord(a[right]), pivotData) == RecordComparator.FOLLOWS)) { right--; } // if the indexes haven't crossed, swap the elements if (left <= right) { int tmp = a[left]; a[left] = a[right]; a[right] = tmp; left++; right--; } } // Sort the left side of the partition if (lowIndex < right) { QuickSort(a, lowIndex, right, comparator); } // Sort the right side of the partition if (left < highIndex) { QuickSort(a, left, highIndex, comparator); } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -