@Override public <K extends Comparable<? super K>, V extends Record, T extends KeyValuePage<K, V>> T combineRecordPages( final List<T> pages, final @Nonnegative int revToRestore, final PageReadTrx pageReadTrx) { assert pages.size() <= 2; final T firstPage = pages.get(0); final long recordPageKey = firstPage.getPageKey(); final T returnVal = firstPage.newInstance( recordPageKey, firstPage.getPageKind(), firstPage.getPreviousReference(), pageReadTrx); if (pages.size() == 2) { returnVal.setDirty(true); } final T latest = pages.get(0); T fullDump = pages.size() == 1 ? pages.get(0) : pages.get(1); assert latest.getPageKey() == recordPageKey; assert fullDump.getPageKey() == recordPageKey; for (final Map.Entry<K, V> entry : latest.entrySet()) { returnVal.setEntry(entry.getKey(), entry.getValue()); } for (final Map.Entry<K, PageReference> entry : latest.referenceEntrySet()) { returnVal.setPageReference(entry.getKey(), entry.getValue()); } // Skip full dump if not needed (fulldump equals latest page). if (pages.size() == 2) { for (final Entry<K, V> entry : fullDump.entrySet()) { if (returnVal.getValue(entry.getKey()) == null) { returnVal.setEntry(entry.getKey(), entry.getValue()); if (returnVal.size() == Constants.NDP_NODE_COUNT) { break; } } } for (final Entry<K, PageReference> entry : fullDump.referenceEntrySet()) { if (returnVal.getPageReference(entry.getKey()) == null) { returnVal.setPageReference(entry.getKey(), entry.getValue()); if (returnVal.size() == Constants.NDP_NODE_COUNT) { break; } } } } return returnVal; }
@Override public <K extends Comparable<? super K>, V extends Record, T extends KeyValuePage<K, V>> T combineRecordPages( final List<T> pages, final @Nonnegative int revToRestore, final PageReadTrx pageReadTrx) { assert pages.size() <= revToRestore; final T firstPage = pages.get(0); final long recordPageKey = firstPage.getPageKey(); final T returnVal = firstPage.newInstance( firstPage.getPageKey(), firstPage.getPageKind(), firstPage.getPreviousReference(), firstPage.getPageReadTrx()); if (pages.size() > 1) { returnVal.setDirty(true); } boolean filledPage = false; for (int i = 0; i < pages.size(); i++) { final T page = pages.get(i); assert page.getPageKey() == recordPageKey; if (filledPage) { break; } for (final Entry<K, V> entry : page.entrySet()) { final K recordKey = entry.getKey(); if (returnVal.getValue(recordKey) == null) { returnVal.setEntry(recordKey, entry.getValue()); if (returnVal.size() == Constants.NDP_NODE_COUNT) { filledPage = true; break; } } } if (!filledPage) { for (final Entry<K, PageReference> entry : page.referenceEntrySet()) { final K recordKey = entry.getKey(); if (returnVal.getPageReference(recordKey) == null) { returnVal.setPageReference(recordKey, entry.getValue()); if (returnVal.size() == Constants.NDP_NODE_COUNT) { filledPage = true; break; } } } } } return returnVal; }
@Override public <K extends Comparable<? super K>, V extends Record, T extends KeyValuePage<K, V>> RecordPageContainer<T> combineRecordPagesForModification( final List<T> pages, final int revToRestore, final PageReadTrx pageReadTrx, final PageReference reference) { final T firstPage = pages.get(0); final long recordPageKey = firstPage.getPageKey(); final List<T> returnVal = new ArrayList<>(2); returnVal.add( firstPage.<T>newInstance( recordPageKey, firstPage.getPageKind(), Optional.of(reference), pageReadTrx)); returnVal.add( firstPage.<T>newInstance( recordPageKey, firstPage.getPageKind(), Optional.of(reference), pageReadTrx)); final T reconstructed = firstPage.<T>newInstance( recordPageKey, firstPage.getPageKind(), Optional.of(reference), pageReadTrx); boolean filledPage = false; for (int i = 0; i < pages.size() && !filledPage; i++) { final T page = pages.get(i); assert page.getPageKey() == recordPageKey; final boolean pageToSerialize = (i == pages.size() - 1 && revToRestore == pages.size()); for (final Entry<K, V> entry : page.entrySet()) { // Caching the complete page. final K key = entry.getKey(); assert key != null; if (!pageToSerialize) { reconstructed.setEntry(key, entry.getValue()); } if (returnVal.get(0).getValue(key) == null) { returnVal.get(0).setEntry(key, entry.getValue()); } if (pageToSerialize && reconstructed.getValue(key) == null) { returnVal.get(1).setEntry(key, entry.getValue()); } if (returnVal.get(0).size() == Constants.NDP_NODE_COUNT) { filledPage = true; break; } } if (!filledPage) { for (final Entry<K, PageReference> entry : page.referenceEntrySet()) { // Caching the complete page. final K key = entry.getKey(); assert key != null; if (!pageToSerialize) { reconstructed.setPageReference(key, entry.getValue()); } if (returnVal.get(0).getPageReference(key) == null) { returnVal.get(0).setPageReference(key, entry.getValue()); } if (pageToSerialize && reconstructed.getPageReference(key) == null) { returnVal.get(1).setPageReference(key, entry.getValue()); } if (returnVal.get(0).size() == Constants.NDP_NODE_COUNT) { filledPage = true; break; } } } } return new RecordPageContainer<>(returnVal.get(0), returnVal.get(1)); }