| | |
| | | import java.util.Map; |
| | | import java.util.NoSuchElementException; |
| | | import java.util.Objects; |
| | | import java.util.Queue; |
| | | import java.util.Set; |
| | | import java.util.concurrent.ConcurrentLinkedDeque; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | import org.forgerock.i18n.slf4j.LocalizedLogger; |
| | |
| | | private static final int BUFFER_SIZE = 16 * 1024; |
| | | |
| | | /** PersistIt implementation of the {@link Cursor} interface. */ |
| | | private static final class CursorImpl implements Cursor<ByteString, ByteString> |
| | | private final class CursorImpl implements Cursor<ByteString, ByteString> |
| | | { |
| | | private ByteString currentKey; |
| | | private ByteString currentValue; |
| | |
| | | public void close() |
| | | { |
| | | // Release immediately because this exchange did not come from the txn cache |
| | | exchange.getPersistitInstance().releaseExchange(exchange); |
| | | releaseExchange(exchange); |
| | | } |
| | | |
| | | @Override |
| | |
| | | /** PersistIt implementation of the {@link Importer} interface. */ |
| | | private final class ImporterImpl implements Importer |
| | | { |
| | | private final Queue<Map<TreeName, Exchange>> allExchanges = new ConcurrentLinkedDeque<>(); |
| | | private final ThreadLocal<Map<TreeName, Exchange>> exchanges = new ThreadLocal<Map<TreeName, Exchange>>() |
| | | { |
| | | @Override |
| | | protected Map<TreeName, Exchange> initialValue() |
| | | { |
| | | final Map<TreeName, Exchange> value = new HashMap<>(); |
| | | allExchanges.add(value); |
| | | return value; |
| | | return new HashMap<>(); |
| | | } |
| | | }; |
| | | |
| | | @Override |
| | | public void close() |
| | | { |
| | | for (Map<TreeName, Exchange> map : allExchanges) |
| | | { |
| | | for (Exchange exchange : map.values()) |
| | | { |
| | | db.releaseExchange(exchange); |
| | | } |
| | | map.clear(); |
| | | } |
| | | PDBStorage.this.close(); |
| | | } |
| | | |
| | |
| | | |
| | | private void createTree(final Transaction txn, final TreeName treeName) |
| | | { |
| | | Exchange ex = null; |
| | | try |
| | | { |
| | | txn.begin(); |
| | | ex = getNewExchange(treeName, true); |
| | | getNewExchange(treeName, true); |
| | | txn.commit(); |
| | | } |
| | | catch (PersistitException e) |
| | |
| | | finally |
| | | { |
| | | txn.end(); |
| | | releaseExchangeSilenty(ex); |
| | | } |
| | | } |
| | | |
| | |
| | | finally |
| | | { |
| | | txn.end(); |
| | | releaseExchangeSilenty(ex); |
| | | } |
| | | } |
| | | |
| | | private void releaseExchangeSilenty(Exchange ex) |
| | | { |
| | | if ( ex != null) |
| | | { |
| | | db.releaseExchange(ex); |
| | | } |
| | | } |
| | | |
| | |
| | | finally |
| | | { |
| | | exchanges.values().remove(ex); |
| | | db.releaseExchange(ex); |
| | | releaseExchange(ex); |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | finally |
| | | { |
| | | db.releaseExchange(ex); |
| | | releaseExchange(ex); |
| | | } |
| | | } |
| | | |
| | |
| | | { |
| | | for (final Exchange ex : exchanges.values()) |
| | | { |
| | | db.releaseExchange(ex); |
| | | releaseExchange(ex); |
| | | } |
| | | exchanges.clear(); |
| | | } |
| | |
| | | } |
| | | finally |
| | | { |
| | | db.releaseExchange(ex); |
| | | releaseExchange(ex); |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | private Exchange getNewExchange(final TreeName treeName, final boolean create) throws PersistitException |
| | | Exchange getNewExchange(final TreeName treeName, final boolean create) throws PersistitException |
| | | { |
| | | return db.getExchange(volume, treeName.toString(), create); |
| | | final Exchange ex = db.getExchange(volume, treeName.toString(), create); |
| | | ex.setMaximumValueSize(Value.MAXIMUM_SIZE); |
| | | return ex; |
| | | } |
| | | |
| | | void releaseExchange(Exchange ex) |
| | | { |
| | | // Don't keep exchanges with enlarged value - let them be GC'd. |
| | | // This is also done internally by Persistit in TransactionPlayer line 197. |
| | | if (ex.getValue().getEncodedBytes().length < Value.DEFAULT_MAXIMUM_SIZE) |
| | | { |
| | | db.releaseExchange(ex); |
| | | } |
| | | } |
| | | |
| | | private StorageImpl newStorageImpl() { |