<commit_before>package be.bagofwords.util;

import be.bagofwords.ui.UI;

import java.util.concurrent.Semaphore;

public class DataLock {

    private static final int NUM_OF_LOCKS = 1000; //Some number an order higher then number of expected simultaneous threads.
    private static final int NUM_OF_PERMITS = 100;

    private final boolean debug;
    private final Semaphore[] locks;

    public DataLock() {
        this(false);
    }

    public DataLock(boolean debug) {
        this.locks = new Semaphore[NUM_OF_LOCKS];
        for (int i = 0; i < NUM_OF_LOCKS; i++) {
            this.locks[i] = new Semaphore(NUM_OF_PERMITS, false);
        }
        this.debug = debug;
    }

    public void lockRead(long key) {
        int lockInd = getLockInd(key);
        locks[lockInd].acquireUninterruptibly(1);
        if (debug) {
            UI.writeStackTrace("Locked read " + lockInd);
        }
    }

    public void unlockRead(long key) {
        int lockInd = getLockInd(key);
        locks[lockInd].release(1);
        if (debug) {
            UI.writeStackTrace("Unlocked read " + lockInd);
        }
    }

    public void lockWrite(long key) {
        int lockInd = getLockInd(key);
        locks[lockInd].acquireUninterruptibly(NUM_OF_PERMITS);
        if (debug) {
            UI.writeStackTrace("Locked write " + lockInd);
        }
    }

    public void unlockWrite(long key) {
        int lockInd = getLockInd(key);
        locks[lockInd].release(NUM_OF_PERMITS);
        if (debug) {
            UI.writeStackTrace("Unlocked write " + lockInd);
        }
    }

    private int getLockInd(long key) {
        if (key < 0) {
            key = -key;
        }
        return (int) (key % NUM_OF_LOCKS);
    }

    public void lockReadAll() {
        for (Semaphore lock : locks) {
            lock.acquireUninterruptibly(1);
        }
        if (debug) {
            UI.writeStackTrace("Locked all read");
        }
    }

    public void unlockReadAll() {
        for (Semaphore lock : locks) {
            lock.release(1);
        }
        if (debug) {
            UI.writeStackTrace("Unlocked all read");
        }
    }

    public void lockWriteAll() {
        for (Semaphore lock : locks) {
            lock.acquireUninterruptibly(NUM_OF_PERMITS);
        }
        if (debug) {
            UI.writeStackTrace("Locked all write");
        }
    }

    public void unlockWriteAll() {
        for (Semaphore lock : locks) {
            lock.release(NUM_OF_PERMITS);
        }
        if (debug) {
            UI.writeStackTrace("Unlocked all write");
        }
    }
}<commit_msg>Added numOfLocks parameter to DataLock<commit_after>package be.bagofwords.util;

import be.bagofwords.ui.UI;

import java.util.concurrent.Semaphore;

public class DataLock {

    private static final int DEFAULT_NUM_OF_LOCKS = 1000;
    private static final int NUM_OF_READ_PERMITS = 1000;

    private final boolean debug;
    private final Semaphore[] locks;

    public DataLock() {
        this(false);
    }

    public DataLock(boolean debug) {
        this(DEFAULT_NUM_OF_LOCKS, debug);
    }

    public DataLock(int numOfLocks, boolean debug) {
        this.locks = new Semaphore[numOfLocks];
        for (int i = 0; i < numOfLocks; i++) {
            this.locks[i] = new Semaphore(NUM_OF_READ_PERMITS, false);
        }
        this.debug = debug;
    }

    public void lockRead(long key) {
        int lockInd = getLockInd(key);
        locks[lockInd].acquireUninterruptibly(1);
        if (debug) {
            UI.writeStackTrace("Locked read " + lockInd);
        }
    }

    public void unlockRead(long key) {
        int lockInd = getLockInd(key);
        locks[lockInd].release(1);
        if (debug) {
            UI.writeStackTrace("Unlocked read " + lockInd);
        }
    }

    public void lockWrite(long key) {
        int lockInd = getLockInd(key);
        locks[lockInd].acquireUninterruptibly(NUM_OF_READ_PERMITS);
        if (debug) {
            UI.writeStackTrace("Locked write " + lockInd);
        }
    }

    public void unlockWrite(long key) {
        int lockInd = getLockInd(key);
        locks[lockInd].release(NUM_OF_READ_PERMITS);
        if (debug) {
            UI.writeStackTrace("Unlocked write " + lockInd);
        }
    }

    private int getLockInd(long key) {
        if (key < 0) {
            key = -key;
        }
        return (int) (key % locks.length);
    }

    public void lockReadAll() {
        for (Semaphore lock : locks) {
            lock.acquireUninterruptibly(1);
        }
        if (debug) {
            UI.writeStackTrace("Locked all read");
        }
    }

    public void unlockReadAll() {
        for (Semaphore lock : locks) {
            lock.release(1);
        }
        if (debug) {
            UI.writeStackTrace("Unlocked all read");
        }
    }

    public void lockWriteAll() {
        for (Semaphore lock : locks) {
            lock.acquireUninterruptibly(NUM_OF_READ_PERMITS);
        }
        if (debug) {
            UI.writeStackTrace("Locked all write");
        }
    }

    public void unlockWriteAll() {
        for (Semaphore lock : locks) {
            lock.release(NUM_OF_READ_PERMITS);
        }
        if (debug) {
            UI.writeStackTrace("Unlocked all write");
        }
    }
}
{'fraction_non_alphanumeric': 0.1048158640226629, 'fraction_numerical': 0.0050991501416430595, 'mean_word_length': 1.9292035398230087, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3946346', 'n_tokens_mistral': 1649, 'n_tokens_neox': 1599, 'n_words': 358}