All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.kolibrifx.plovercrest.server.internal.engine.DeferredReader Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2010-2017, KolibriFX AS. Licensed under the Apache License, version 2.0.
 */

package com.kolibrifx.plovercrest.server.internal.engine;

import org.apache.log4j.Logger;
import com.kolibrifx.plovercrest.client.TableClosedException;
import com.kolibrifx.plovercrest.server.ReadObserver;
import com.kolibrifx.plovercrest.server.internal.engine.TableMapper.ReadIterator;

public class DeferredReader {
    private static final Logger log = Logger.getLogger(DeferredReader.class);

    private ReadIterator iterator = null;
    private final DeferredTableMapper mapper;

    public DeferredReader(final DeferredTableMapper mapper) {
        this.mapper = mapper;
    }

    private ReadIterator getIterator() {
        if (iterator == null) {
            // Note that getReadIterator(0) can throw a TableClosedException
            iterator = mapper.getMapper().getReadIterator(0);
        }
        mapper.recordUse();
        return iterator;
    }

    private void handleTableClosed(final TableClosedException e) {
        if (mapper.isClosed()) {
            // the table really is closed, so rethrow
            throw e;
        }
        try {
            if (iterator == null) {
                // can happen if the first getIterator() call failed
                iterator = mapper.getMapper().getReadIterator(0);
            } else {
                // the table mapper has been evicted, so recreate the read iterator at the same index
                // getting the entry index from the old iterator should work even if the mapper has been closed
                final long entryIndex = iterator.getEntryIndex();
                iterator = mapper.getMapper().getReadIterator(entryIndex);
            }
        } catch (final TableClosedException e2) {
            // Yes, this is possible when really stressing the cache. Should be very rare in practice, though.
            log.warn("Caught TableClosedException during exception handling");
        }
    }

    public  T read(final ReadObserver observer) {
        while (true) {
            try {
                return getIterator().next(observer);
            } catch (final TableClosedException e) {
                handleTableClosed(e);
            }
        }
    }

    public long seekTakePrevious(final long desiredTimestamp) {
        while (true) {
            try {
                return getIterator().seekTakePrevious(desiredTimestamp);
            } catch (final TableClosedException e) {
                handleTableClosed(e);
            }
        }
    }

    public long seekTakeNext(final long desiredTimestamp) {
        while (true) {
            try {
                return getIterator().seekTakeNext(desiredTimestamp);
            } catch (final TableClosedException e) {
                handleTableClosed(e);
            }
        }
    }

    public void seekToEntryIndex(final long entryIndex) {
        while (true) {
            try {
                getIterator().seekToEntryIndex(entryIndex);
                return;
            } catch (final TableClosedException e) {
                handleTableClosed(e);
            }
        }
    }

    public long getEntryIndex() {
        while (true) {
            try {
                return getIterator().getEntryIndex();
            } catch (final TableClosedException e) {
                handleTableClosed(e);
            }
        }
    }

    public long getLastTimestamp() {
        return mapper.getLastTimestamp();
    }

    public long getFirstTimestamp() {
        return mapper.getFirstTimestamp();
    }

    public long getLastValidTimestamp() {
        return mapper.getLastValidTimestamp();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy