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

ru.taskurotta.service.storage.MemoryBrokenProcessService Maven / Gradle / Ivy

package ru.taskurotta.service.storage;

import ru.taskurotta.service.console.model.BrokenProcess;
import ru.taskurotta.service.console.model.SearchCommand;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * User: stukushin
 * Date: 11.10.13
 * Time: 18:28
 */
public class MemoryBrokenProcessService implements BrokenProcessService {

    private ConcurrentHashMap> deciderActorIds = new ConcurrentHashMap<>();
    private ConcurrentHashMap> brokenActorIds = new ConcurrentHashMap<>();
    private ConcurrentHashMap> times = new ConcurrentHashMap<>();
    private ConcurrentHashMap> errorMessages = new ConcurrentHashMap<>();
    private ConcurrentHashMap> errorClassNames = new ConcurrentHashMap<>();
    private ConcurrentHashMap> stackTraces = new ConcurrentHashMap<>();

    private ConcurrentHashMap brokenProcess = new ConcurrentHashMap<>();

    private static final Lock lock = new ReentrantLock();

    @Override
    public void save(BrokenProcess brokenProcess) {

        UUID processId = brokenProcess.getProcessId();

        addProcessId(deciderActorIds, brokenProcess.getStartActorId(), processId);
        addProcessId(brokenActorIds, brokenProcess.getBrokenActorId(), processId);
        addProcessId(times, brokenProcess.getTime(), processId);
        addProcessId(errorMessages, brokenProcess.getErrorMessage(), processId);
        addProcessId(errorClassNames, brokenProcess.getErrorClassName(), processId);
        addProcessId(stackTraces, brokenProcess.getStackTrace(), processId);

        this.brokenProcess.put(processId, brokenProcess);
    }

    @Override
    public Collection find(SearchCommand searchCommand) {

        if (searchCommand == null) {
            return new ArrayList<>();
        }

        List processIds = new ArrayList<>();
        Collection result = new ArrayList<>();

        if (searchCommand.getProcessId() != null) {
            result.add(brokenProcess.get(searchCommand.getProcessId()));
            return result;
        }

        if (searchCommand.getStartActorId() != null) {
            searchByStartString(searchCommand.getStartActorId(), deciderActorIds, processIds);
        }

        if (searchCommand.getBrokenActorId() != null) {
            searchByStartString(searchCommand.getBrokenActorId(), brokenActorIds, processIds);
        }

        if (searchCommand.getStartPeriod() > 0 && searchCommand.getEndPeriod() > 0) {
            Set>> entries = times.entrySet();
            for (Map.Entry> entry: entries) {
                if (entry.getKey() > searchCommand.getStartPeriod() && entry.getKey() < searchCommand.getEndPeriod()) {
                    merge(entry.getValue(), processIds);
                }
            }
        } else if (searchCommand.getStartPeriod() > 0 && searchCommand.getEndPeriod() < 0) {
            Set>> entries = times.entrySet();
            for (Map.Entry> entry: entries) {
                if (entry.getKey() > searchCommand.getStartPeriod()) {
                    merge(entry.getValue(), processIds);
                }
            }
        } else if (searchCommand.getStartPeriod() < 0 && searchCommand.getEndPeriod() > 0) {
            Set>> entries = times.entrySet();
            for (Map.Entry> entry: entries) {
                if (entry.getKey() < searchCommand.getEndPeriod()) {
                    merge(entry.getValue(), processIds);
                }
            }
        }

        if (searchCommand.getErrorMessage() != null) {
            searchByStartString(searchCommand.getErrorMessage(), errorMessages, processIds);
        }

        if (searchCommand.getErrorClassName() != null) {
            searchByStartString(searchCommand.getErrorClassName(), errorClassNames, processIds);
        }

        for (UUID processId : processIds) {
            BrokenProcess brokenProcess = this.brokenProcess.get(processId);
            if (brokenProcess != null) {
                result.add(brokenProcess);
            }
        }

        return result;
    }

    @Override
    public Collection findAll() {
        return brokenProcess.values();
    }

    @Override
    public void delete(UUID processId) {

        if (processId == null) {
            return;
        }

        deleteProcessId(deciderActorIds, processId);
        deleteProcessId(brokenActorIds, processId);
        deleteProcessId(times, processId);
        deleteProcessId(errorMessages, processId);
        deleteProcessId(errorClassNames, processId);
        deleteProcessId(stackTraces, processId);

        brokenProcess.remove(processId);
    }

    @Override
    public void deleteCollection(Collection processIds) {
        for (UUID processId : processIds) {
            delete(processId);
        }
    }

    private void addProcessId(ConcurrentHashMap> map, String key, UUID processId) {

        if (key == null) {
            return;
        }

        CopyOnWriteArraySet processIds = map.get(key);

        if (processIds == null) {
            try {
                lock.lock();

                processIds = new CopyOnWriteArraySet<>();
                processIds.add(processId);

                CopyOnWriteArraySet previous = map.putIfAbsent(key, processIds);
                if (previous != null) {
                    map.get(key).add(processId);
                }
            } finally {
                lock.unlock();
            }
        } else {
            processIds.add(processId);
        }
    }

    private void addProcessId(ConcurrentHashMap> map, Long key, UUID processId) {

        if (key == null) {
            return;
        }

        CopyOnWriteArraySet processIds = map.get(key);

        if (processIds == null) {
            try {
                lock.lock();

                processIds = new CopyOnWriteArraySet<>();
                processIds.add(processId);

                CopyOnWriteArraySet previous = map.putIfAbsent(key, processIds);
                if (previous != null) {
                    map.get(key).add(processId);
                }
            } finally {
                lock.unlock();
            }
        } else {
            processIds.add(processId);
        }
    }

    private void searchByStartString(String prefix, ConcurrentHashMap> map, Collection result) {
        Set>> entries = map.entrySet();

        for (Map.Entry> entry : entries) {
            if (entry.getKey().startsWith(prefix)) {
                merge(entry.getValue(), result);
            }
        }
    }

    private Collection merge(Collection from, Collection to) {

        for (UUID uuid : from) {
            if (to.contains(uuid)) {
                continue;
            }

            to.add(uuid);
        }

        return to;
    }

    private void deleteProcessId(ConcurrentHashMap> map, UUID processId) {

        if (processId == null) {
            return;
        }

        Collection> values = map.values();
        for (CopyOnWriteArraySet processIds : values) {
            processIds.remove(processId);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy