<commit_before>package com.lieuu.fetcher;

import java.lang.ref.SoftReference;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import com.lieuu.fetcher.exception.FetcherException;
import com.lieuu.fetcher.exception.FetcherNotReadyException;

class CachingFetcher<T> implements Fetcher<T> {

    private final ReadWriteLock objLock;
    private final ReadWriteLock exceptionLock;

    private final Fetcher<T> fetcher;
    private SoftReference<T> prevObj;
    private SoftReference<FetcherException> prevException;

    public CachingFetcher(final Fetcher<T> fetcher) {
        this.objLock = new ReentrantReadWriteLock();
        this.exceptionLock = new ReentrantReadWriteLock();
        this.fetcher = fetcher;
        this.prevObj = new SoftReference<>(null);
        this.prevException = new SoftReference<>(null);
    }

    @Override
    public T fetch() throws FetcherException {

        try {

            this.exceptionLock.readLock().lock();

            try {
                final FetcherException exceptionCurrent = this.prevException.get();

                if ((exceptionCurrent != null)
                    && !(exceptionCurrent.getCause() instanceof FetcherNotReadyException)) {
                    throw exceptionCurrent;
                }
            }
            finally {
                this.exceptionLock.readLock().unlock();
            }

            this.objLock.readLock().lock();

            try {
                final T objectCurrent = this.prevObj.get();

                if (objectCurrent != null) {
                    return objectCurrent;
                }
            }
            finally {
                this.objLock.readLock().unlock();
            }

            final T value = this.fetcher.fetch();

            if (value == null) {
                throw new FetcherException(new NullPointerException("Value from fetcher was null"));
            }
            else {
                this.setPrevObj(value);// store the previously retrieved value
                                       // for faster retrieval
                return value;
            }

        }
        catch (final Exception e) {

            this.setPrevException(e);

            this.exceptionLock.readLock().lock();

            try {
                throw this.prevException.get();
            }
            finally {
                this.exceptionLock.readLock().unlock();
            }

        }
<commit_msg>Modified to not use readlock for thrown exception<commit_after>package com.lieuu.fetcher;

import java.lang.ref.SoftReference;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import com.lieuu.fetcher.exception.FetcherException;
import com.lieuu.fetcher.exception.FetcherNotReadyException;

class CachingFetcher<T> implements Fetcher<T> {

    private final ReadWriteLock objLock;
    private final ReadWriteLock exceptionLock;

    private final Fetcher<T> fetcher;
    private SoftReference<T> prevObj;
    private SoftReference<FetcherException> prevException;

    public CachingFetcher(final Fetcher<T> fetcher) {
        this.objLock = new ReentrantReadWriteLock();
        this.exceptionLock = new ReentrantReadWriteLock();
        this.fetcher = fetcher;
        this.prevObj = new SoftReference<>(null);
        this.prevException = new SoftReference<>(null);
    }

    @Override
    public T fetch() throws FetcherException {

        try {

            this.exceptionLock.readLock().lock();

            try {
                final FetcherException exceptionCurrent = this.prevException.get();

                if ((exceptionCurrent != null)
                    && !(exceptionCurrent.getCause() instanceof FetcherNotReadyException)) {
                    throw exceptionCurrent;
                }
            }
            finally {
                this.exceptionLock.readLock().unlock();
            }

            this.objLock.readLock().lock();

            try {
                final T objectCurrent = this.prevObj.get();

                if (objectCurrent != null) {
                    return objectCurrent;
                }
            }
            finally {
                this.objLock.readLock().unlock();
            }

            final T value = this.fetcher.fetch();

            if (value == null) {
                throw new FetcherException(new NullPointerException("Value from fetcher was null"));
            }
            else {
                this.setPrevObj(value); // store the previously retrieved value
                                        // for faster retrieval
                return value;
            }

        }
        catch (final Exception e) {

            this.setPrevException(e);
            throw e;

        }

{'fraction_non_alphanumeric': 0.08791208791208792, 'fraction_numerical': 0.0, 'mean_word_length': 1.7724137931034483, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3949717', 'n_tokens_mistral': 1229, 'n_tokens_neox': 1176, 'n_words': 255}