Объединить два хеш-карты в RecursiveTask - PullRequest
0 голосов
/ 07 апреля 2019

Я хотел бы просмотреть все файлы из определенной папки и в каждом файле подсчитать определенные слова. Это должно быть сделано через пул потоков, где каждый поток должен быть создан, только если объединенный размер файлов больше, чем заданный размер файла. Итак, в другом классе я нашел все файлы в данной папке и там я звоню forkJoinPoolInstance.submit(new JobFileTask(files));

Я проверил некоторые другие потоки на stackoverflow и узнал о слиянии в HashMaps, но это не решает мою проблему. Если я использую код, как написано ниже, слиянием, то все значения из всех файлов каждой папки для определенного ключа будут нулевыми. И если бы вместо этого вызова слияния я поставил mapToReturn.putAll(readFile(f));, он бы считал только одно слово на файл, даже если бы было больше вхождений данных ключевых слов. Что мне здесь не хватает?

public class JobFileTask extends RecursiveTask<Map<String, Integer>>
{
    private File[] files;

    public JobFileTask (File[] f)
    {
        this.files = f;
    }

    @Override
    protected Map<String, Integer> compute()
    {
        System.out.println("Computing... ");
        Map<String, Integer> mapToReturn = new ConcurrentHashMap<>();
        long currentSize = 0;
        ArrayList<File> newFiles = new ArrayList<>();
        ArrayList<File> otherFiles = new ArrayList<>();

        if (files.length == 0)
        {
            return mapToReturn;
        }

        for (File f: files)
        {
            currentSize += f.length();
            if (currentSize <= Main.getScanningSizeLimit())
            {
                newFiles.add(f);
                Map<String, Integer> temp = readFile(f);
                mapToReturn.entrySet()
                   .forEach(entry -> temp.merge(
                            entry.getKey(),
                            entry.getValue(),
                            (key, value) -> entry.getValue() + value));
            }
            else
            {
                ForkJoinTask<Map<String, Integer>> forkTask = new JobFileTask((File[]) newFiles.toArray(new File[newFiles.size()]));

                forkTask.fork();

                for (File fs: files)
                {
                    if (!newFiles.contains(fs))
                    {
                        otherFiles.add(fs);
                    }
                }

                JobFileTask callTask = new JobFileTask((File[]) otherFiles.toArray(new File[otherFiles.size()]));

                Map<String, Integer> forkResult = callTask.compute();

                Map<String, Integer> callResult = forkTask.join();

                mapToReturn.putAll(forkResult);
                mapToReturn.putAll(callResult);
                break;
            }
        }

        return mapToReturn;
    }

    public Map<String, Integer> readFile(File f)
    {
        Map<String, Integer> toReturn = new ConcurrentHashMap<>();
        try
        {
            String line = "";
            BufferedReader bufferedReader = new BufferedReader(new FileReader(f));
            while ((line = bufferedReader.readLine()) != null)
            {
                for (String k: Main.getKeywords())
                {
                    if (line.contains(k))
                    {
                        if (toReturn.containsKey(k))
                        {
                            toReturn.put(k, toReturn.get(k)+1);
                        }
                        else
                        {
                            toReturn.put(k, 1);
                        }
                    }
                }
            }
            bufferedReader.close();
        } 
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return toReturn;
    }
...