package com.aptana.ide.internal.index.core;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import com.aptana.ide.index.core.Index;
import com.aptana.ide.index.core.QueryResult;
import com.aptana.ide.index.core.SearchPattern;
public class MemoryIndex
{
private static final int MERGE_THRESHOLD = 100;
private HashMap<String, Map<String, Set<String>>> documentsToTable;
public MemoryIndex()
{
documentsToTable = new HashMap<String, Map<String, Set<String>>>();
}
public void addEntry(String category, String key, String filePath)
{
Map<String, Set<String>> categoriesToWords = documentsToTable.get(filePath);
if (categoriesToWords == null)
{
categoriesToWords = new HashMap<String, Set<String>>();
documentsToTable.put(filePath, categoriesToWords);
}
Set<String> words = categoriesToWords.get(category);
if (words == null)
{
words = new HashSet<String>();
categoriesToWords.put(category, words);
}
words.add(key);
}
Set<String> getDocumentNames()
{
return documentsToTable.keySet();
}
public int numberOfChanges()
{
return documentsToTable.size();
}
public boolean hasChanged()
{
return numberOfChanges() > 0;
}
Map<String, Set<String>> getCategoriesForDocument(String docname)
{
return documentsToTable.get(docname);
}
public Map<String, QueryResult> addQueryResults(String[] categories, String key, int matchRules,
Map<String, QueryResult> results)
{
if (results == null)
results = new HashMap<String, QueryResult>();
for (Map.Entry<String, Map<String, Set<String>>> entry : documentsToTable.entrySet())
{
Map<String, Set<String>> categoriesToWords = entry.getValue();
if (categoriesToWords == null)
continue;
for (String category : categories)
{
Set<String> words = categoriesToWords.get(category);
// When we're looking for exact matches, case sensitive, just ask wordset if it contains key!
if (matchRules == (SearchPattern.EXACT_MATCH | SearchPattern.CASE_SENSITIVE))
{
if (words.contains(key))
{
QueryResult result = results.get(key);
if (result == null)
result = new QueryResult(key);
result.addDocumentName(entry.getKey());
results.put(key, result);
}
}
else
{
// Otherwise we need to check each word individually
for (String word : words)
{
if (Index.isMatch(key, word, matchRules))
{
QueryResult result = results.get(word);
if (result == null)
result = new QueryResult(word);
result.addDocumentName(entry.getKey());
results.put(key, result);
}
}
}
}
}
return results;
}
public boolean shouldMerge()
{
return numberOfChanges() >= MERGE_THRESHOLD;
}
Map<String, Map<String, Set<String>>> getDocumentsToReferences()
{
return Collections.unmodifiableMap(documentsToTable);
}
public void remove(String documentName)
{
this.documentsToTable.put(documentName, null);
}
public void removeCategories(String[] categoryNames)
{
for (Map<String, Set<String>> categoriesToWords : documentsToTable.values())
{
if (categoriesToWords != null)
{
for (String category : categoryNames)
categoriesToWords.remove(category);
}
}
}
}