package org.ariadne_eu.utils.rest; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.json.JSONObject; //import IndexBuilder.Index; public class InMemoryEngine implements SearchEnginePlugIn { /*private class MetadataElement { String[] elementNames; String delimiter; ElementHandler elementHandler; Pattern[] pattern; public MetadataElement(String[] elementNam){ elementNames = elementNam; pattern = new Pattern[elementNam.length]; for (int i = 0; i<elementNam.length;i++) pattern[i] = Pattern.compile("<"+elementNam[i]+".*?>(.*?)</"+elementNam[i]+">"); } }*/ //private static InMemoryEngine myInstance; private int nrOfNodes = 0; private int nodeSize = 0; private int BENCHMARK_OFFSET; private int[] idOffset; ArrayList<Integer> idOffsetList = new ArrayList<Integer>(); private SearchNode[] nodes; //private String[] searchTerms; //All the search terms such as "sbj=mathematics", "lng=nl", etc private String[] facets; private String loadPath = ""; private String[] parameters = new String[0]; //private int fstNode = -1; //private int lstNode = -1; //private HashMap<String,MetadataElement> metadataMap = new HashMap<String,MetadataElement>(); /** * */ public Object clone() throws CloneNotSupportedException { throw new CloneNotSupportedException(); } /* (non-Javadoc) * @see SearchEngine#initialise() */ public String[] getParameters(){ return parameters; } public void initialise(String[] arg) throws Exception { parameters = arg; nodeSize = 16384; BENCHMARK_OFFSET = 1000000; loadPath = arg[0]; int fstNode = Integer.parseInt(arg[1].trim()); int lstNode = Integer.parseInt(arg[2].trim()); int benchmarkMultiplier = Integer.parseInt(arg[3].trim()); if (benchmarkMultiplier < 1) benchmarkMultiplier = 1; nrOfNodes = 0; //nodeSize = 0; //searchTerms = new String[0]; facets = null; nodes = new SearchNode[nrOfNodes]; //metadataMap.put("title", new MetadataElement(new String[] {"(lom:)?general","(lom:)?title","(lom:)?string"})); //metadataMap.put("description", new MetadataElement(new String[] {"(lom:)?general","(lom:)?description","(lom:)?string"})); //metadataMap.put("keywords", new MetadataElement(new String[] {"(lom:)?general","(lom:)?keyword","(lom:)?string"})); //metadataMap.put("location", new MetadataElement(new String[] {"(lom:)?technical","(lom:)?location"})); int nrOfInputNodes = (lstNode - fstNode + 1) ; nrOfNodes = nrOfInputNodes*benchmarkMultiplier ; nodes = new SearchNode[nrOfNodes]; int idOffset = 0; for (int i=0;i<nrOfInputNodes;i++){ nodes[i] = new SearchNode(i); String fileNam = "part"+(new DecimalFormat("00").format(i+fstNode)); System.out.println("Loading node: "+(i+fstNode)); idOffsetList.add(idOffset); idOffset = nodes[i].loadTerms(loadPath,fileNam,idOffset); nodes[i].loadPointers(loadPath,fileNam); } for (int j=1; j<benchmarkMultiplier ;j++){ for (int i=0;i<nrOfInputNodes;i++){ System.out.println("Copy into node: "+(i+(lstNode + 1)*j)); nodes[i+(lstNode + 1)*j].copyFrom(nodes[i],j*BENCHMARK_OFFSET); } } } /** * * @param dir * @param firstNode * @param lastNode * @throws Exception */ /*public void load(String dir,int firstNode,int lastNode) throws Exception{ if (loadPath != dir ||fstNode!=firstNode ||lstNode!=lastNode){ //nrOfNodes = lastNode - firstNode + 1; nrOfNodes = lastNode+1; nodes = new SearchNode[nrOfNodes]; for (int i=0;i<nodes.length;i++){ nodes[i] = new SearchNode(i); } for (int i=firstNode;i<=lastNode;i++){ String NodeNr = new DecimalFormat("00").format(i); System.out.println("Loading node: "+i); nodes[i].loadTerms(dir); nodes[i].loadPointers(dir); } } }*/ /** * * @param dir * @param firstNode * @param lastNode * @throws Exception */ /*public void loadBenchmark(String dir,int firstNode,int lastNode, int benchmarkMultiplier ) throws Exception{ //nrOfNodes = (lastNode - firstNode + 1)*3; nrOfNodes = (lastNode + 1)*benchmarkMultiplier ; nodes = new SearchNode[nrOfNodes]; for (int i=0;i<nodes.length;i++){ nodes[i] = new SearchNode(i); } for (int i=firstNode;i<=lastNode;i++){ //String NodeNr = new DecimalFormat("00").format(firstNode+i); System.out.println("Loading node: "+i); nodes[i].loadTerms(dir); nodes[i].loadPointers(dir); for (int j=1; j<benchmarkMultiplier ;j++){ System.out.println("Copy into node: "+(i+(lastNode + 1)*j)); nodes[i+(lastNode + 1)*j].copyFrom(nodes[i],j*BENCHMARK_OFFSET); } } }*/ /** * * @param facets */ public void setFacets(String [] facets){ this.facets = facets; } /** * @param request is an HttpServletRequest * @returns response is a HttpServletResponse */ public void search(HttpServletRequest request, HttpServletResponse response) { long timeInMillis = 0; long startTimeInMillis = System.currentTimeMillis(); String js = request.getParameter("json"); Query qry = new Query(); QueryResult qryResult = new QueryResult(qry); try { if (js!=null) { JSONObject jo = new JSONObject(js); qry.parseJson(jo); } else { qry.parseURL(request); } //Search qryResult = search(qry); } catch (Exception ex) { System.out.println(ex.getMessage()); ex.printStackTrace (); } String result = qryResult.toJson(); timeInMillis = System.currentTimeMillis() - startTimeInMillis; //float timeInSeconds = (new Float(timeInMillis).floatValue())/1000; if (result.endsWith("}}")){ result = result.substring(0, result.length() - 2) + ",\"processingTime\":\"" + timeInMillis + "\"}}"; } else { result = "{\"result\":{\"processingTime\":"+timeInMillis+"}}"; } PrintWriter out = null; try { response.setContentType("text/plain; charset=UTF-8"); out = new PrintWriter(new OutputStreamWriter(response.getOutputStream(), "UTF8"), true); out.println(result); out.close(); } catch (Exception ex) { System.out.println(ex.getMessage()); ex.printStackTrace (); } if (out!=null) out.close(); } /* (non-Javadoc) * @see SearchEngine#search(Query) */ public QueryResult search(Query qry) { //System.out.println(qry); qry.searchEngine = this; if (qry.facets == null) qry.facets = facets; int dimRes = 0; int totalNrOfResults = 0; int idsTo = qry.idListOffset+qry.idListSize; int[] temp = new int[nodes.length*idsTo]; HashMap<String,Integer> facetsMap = new HashMap<String,Integer>(); for (int i=0;i<nodes.length;i++){ //System.out.println("Searching node: "+i); QueryResult res = nodes[i].search(qry); //System.out.println("NrOfResults for node "+i+" = "+res.nrOfResults); int nrOfResults = res.nrOfResults; //TODO We need to merge results differently, using a heap for the ranking if (nrOfResults>idsTo) nrOfResults=idsTo; for (int j=0;j<nrOfResults;j++) temp[dimRes++]=res.intIDs[j]; totalNrOfResults = totalNrOfResults + res.nrOfResults; for (int j=0;j<res.facetCounts.length;j++){ if ((res.facetCounts[j]>0)){ String fk = res.facetKeys[j]; if (!facetsMap.containsKey(fk)){ facetsMap.put(fk, res.facetCounts[j]); } else { facetsMap.put(fk, facetsMap.get(fk)+res.facetCounts[j]); } } } } QueryResult result = new QueryResult(qry); result.nrOfResults = totalNrOfResults; if (dimRes>idsTo) dimRes=idsTo; for (int i=qry.idListOffset;i<dimRes;i++) result.intIDs[i - qry.idListOffset]=temp[i]; result.nrOfIDs = dimRes - qry.idListOffset; String[] facetKeys = new String[facetsMap.size()]; facetsMap.keySet().toArray(facetKeys); Arrays.sort(facetKeys); result.facetKeys = facetKeys; result.facetCounts = new int[facetKeys.length]; for (int i=0;i<facetKeys.length;i++){ result.facetCounts[i] = facetsMap.get(result.facetKeys[i]); } return result; } /** * * @param nr * @return */ public SearchNode getNode(int nr) { return nodes[nr]; } /* public LOMResult[] getLOMResults(int[] ids) throws Exception { LOMResult[] r = new LOMResult[ids.length]; for (int i=0;i<ids.length;i++) r[i] = getLOMResult(ids[i]); return r; } */ public String getJsonResult(int id) throws Exception { //LOMResult r = new LOMResult(); int properID = id % BENCHMARK_OFFSET; //TODO Change to a variable offset using idOffset int node = (properID - 1) / nodeSize; int nr = properID - (node * nodeSize); return nodes[node].getJsonResult(nr); //return nodes[node].getLOMResult(nr); } /* public LOMResult getLOMResult(String dir,int id) { FileInputStream fis = null; ZipInputStream zis = null; //ZipFile zif = null; LOMResult r = new LOMResult(); int node = (id - 1) / nodeSize; int nr = id - (node * nodeSize); String nodeStr = new DecimalFormat("00").format(node); String inFile = "part"+nodeStr+".zip"; try { fis = new FileInputStream(dir+inFile); //zif = new ZipFile(dir+inFile); zis = new ZipInputStream(new BufferedInputStream(fis)); //ZipEntry entry = null; String content=""; for (int i=1;i<nr;i++)zis.getNextEntry(); if ((zis.getNextEntry()) != null) { Scanner s = new Scanner(zis); s.nextLine(); while (s.hasNext()){ content = content+" "+s.nextLine().trim(); } r.title = extractContent(metadataMap.get("title"),content,0); r.description = extractContent(metadataMap.get("description"),content,0); r.keywords = extractContent(metadataMap.get("keywords"),content,0); r.location = extractContent(metadataMap.get("location"),content,0); } } catch (Exception ex) { ex.printStackTrace(); } return r; } */ /* private String extractContent(MetadataElement el, String content, int elementPos){ //System.out.println(content); //System.out.println("Looking for: "+el.elementNames[elementPos]); String res = ""; Matcher matcher = (el.pattern[elementPos]).matcher(content); while (matcher.find()) { if (elementPos<el.pattern.length-1){ return extractContent(el, matcher.group(2),elementPos+1); } else { return matcher.group(2); } } return res; } */ }