在java

时间:2017-03-11 19:19:57

标签: java file memory inverted-index

我很好奇如何在不适合内存的数据上创建反向索引。所以现在我正在读取文件目录并根据文件内的内容索引文件,我使用HashMap来存储索引。下面的代码是我使用的函数的片段,我在整个目录上调用该函数。如果这个目录很大并且HashMap不能适合所有条目,我该怎么办?是的,这听起来像是过早优化。我只是玩得开心。我不想使用Lucene,所以甚至不要提及它,因为我很难看到这是“索引”的主要答案。这个HashMap是我唯一的约束,其他所有内容都存储在文件中,以便以后轻松引用。

我只是好奇我是如何做到这一点的,因为它将它存储在地图中就像这样

keyword -> file1,file2,file3,etc..(locations)
keyword2 -> file9,file11,file13,etc..(locations)

我的想法是创建一个文件,如何能够更新自己,就像上面的格式,但我觉得这不高效。

代码段

        br = new BufferedReader(new FileReader(file));

        while ((line = br.readLine()) != null) {
            for (String _word : line.split("\\W+")) {
                word = _word.toLowerCase();

                if (!ignore_words.contains(word)) {

                    fileLocations = index.get(word);

                    if (fileLocations == null) {
                        fileLocations = new LinkedList<Long>();
                        index.put(word, fileLocations);
                    }
                    fileLocations.add(file_offset);
                }
            }
        }

        br.close();

更新

所以我设法得到了一些东西,但是表现明智我觉得这很慢,特别是如果有大量的数据。我基本上创建了一个文件,只需要在单词出现的每一行上都有单词和偏移量。让它命名为index.txt

它的格式是这样的

word1:offset
word2:offset
word1:offset <-encountered again.
word3:offset
etc...

然后我为每个单词创建了多个文件,并在每次在index.txt文件中遇到时将偏移量附加到该文件。

所以基本上word文件的格式就是这样

word1.txt -- Format
word1:offset1:offset2:offset3:offset4...and so on

每次在index.txt文件中遇到word1时,它会将其附加到word1.txt文件并添加到结尾。

然后最后,我浏览了我创建的所有单词文件,并覆盖index.txt文件,索引文件中的最终输出看起来像这样

word1:offset1:offset2:offset3:offset4:...
word2:offset9:offset11:offset13:offset14:...
etc..

然后为了完成它,我删除了所有单词文件。

令人讨厌的代码片段如下,其数量相当可观。

public void createIndex(String word, long file_offset)
{
    PrintWriter writer;
    try {
        writer = new PrintWriter(new FileWriter(this.file,true));
        writer.write(word + ":" + file_offset + "\n");
        writer.close();
    }
    catch (IOException ioe)
    {
        ioe.printStackTrace();
    }

}

public void mergeFiles()
{
    String line;
    String wordLine;
    String[] contents;
    String[] wordContents;
    BufferedReader reader;
    BufferedReader mergeReader;
    PrintWriter writer;
    PrintWriter mergeWriter;

    try {
        reader = new BufferedReader(new FileReader(this.file));

        while((line = reader.readLine()) != null)
        {
            contents = line.split(":");
            writer = new PrintWriter(new FileWriter(
                    new File(contents[0] + ".txt"),true));

            if(this.words.get(contents[0]) == null) 
            {
                this.words.put(contents[0], contents[0]);
                writer.write(contents[0] + ":");
            }

            writer.write(contents[1] + ":");

            writer.close();
        }
        //This could be put in its own method below.
        mergeWriter = new PrintWriter(new FileWriter(this.file));

        for(String word : this.words.keySet())
        {
            mergeReader = new BufferedReader(
                    new FileReader(new File(word + ".txt")));
            while((wordLine = mergeReader.readLine()) != null)
            {
                mergeWriter.write(wordLine + "\n");
            }

        }
        mergeWriter.close();

        deleteFiles();

    } 
    catch(IOException ioe)
    {
        ioe.printStackTrace();
    }
}


public void deleteFiles()
{
    File toDelete;
    for(String word : this.words.keySet())
    {
        toDelete = new File(word + ".txt");
        if(toDelete.exists())
        {
            toDelete.delete();
        }
    }
}

0 个答案:

没有答案