protected virtual List<Record> Search(KNearestNeighborQuery kNN, Node node, List<BufferItem> changeList) { PriorityQueue<NodeEntry, Single> proximityQueue = new PriorityQueue<NodeEntry, Single>(); List<Record> results = new List<Record>(kNN.K); List<BufferItem> deletions = new List<BufferItem>(); foreach(BufferItem change in changeList) if(change.Operation == Operation.Delete) deletions.Add(change); foreach(BufferItem deletion in deletions) changeList.Remove(deletion); foreach (BufferItem insertion in changeList) proximityQueue.Enqueue(insertion.Entry, GetDistance(kNN.X, kNN.Y, insertion.Entry.MinimumBoundingBox) * -1); EnqueNodeEntries(kNN, node, proximityQueue); while (results.Count < kNN.K && proximityQueue.Count > 0) { NodeEntry closestEntry = proximityQueue.Dequeue().Value; if (closestEntry is LeafEntry) { Boolean entryDeleted = false; foreach (BufferItem deletion in deletions) if (closestEntry.Child.Equals(deletion.Entry.Child)) entryDeleted = true; if (!entryDeleted) results.Add(Cache.LookupRecord(closestEntry.Child)); } else EnqueNodeEntries(kNN, Cache.LookupNode(closestEntry.Child), proximityQueue); } while (results.Contains(null)) results.Remove(null); for(int i = 0; i < results.Count; i++) for(int j = i; j < results.Count; j++) { if (results[i].BoundingBox.MinX == results[j].BoundingBox.MinX && results[i].BoundingBox.MinY == results[j].BoundingBox.MinY && results[i].BoundingBox.MaxX == results[j].BoundingBox.MaxX && results[i].BoundingBox.MaxY == results[j].BoundingBox.MaxY) { if (results[i].RecordID.CompareTo(results[j].RecordID) > 0) { Record temp = results[i]; results[i] = results[j]; results[j] = temp; } } else break; } return results; }
protected override List<Record> Search(KNearestNeighborQuery kNN, Node node) { return Search(kNN, node, Condense(Buffer.Buffer)); }
protected virtual void EnqueNodeEntries(KNearestNeighborQuery kNN, Node node, PriorityQueue<NodeEntry, Single> proximityQueue) { foreach (NodeEntry entry in node.NodeEntries) proximityQueue.Enqueue(entry, GetDistance(kNN.X, kNN.Y, entry.MinimumBoundingBox) * -1); }
protected virtual List<Record> Search(KNearestNeighborQuery kNN, Node node) { PriorityQueue<NodeEntry, Single> proximityQueue = new PriorityQueue<NodeEntry, Single>(); List<Record> results = new List<Record>(kNN.K); EnqueNodeEntries(kNN, node, proximityQueue); while (results.Count < kNN.K && proximityQueue.Count > 0) { NodeEntry closestEntry = proximityQueue.Dequeue().Value; if (closestEntry is LeafEntry) { Record closestRecord = Cache.LookupRecord(closestEntry.Child); results.Add(closestRecord); } else { Node closestNode = Cache.LookupNode(closestEntry.Child); EnqueNodeEntries(kNN, closestNode, proximityQueue); } } for(int i = 0; i < results.Count; i++) for(int j = i; j < results.Count; j++) { if (results[i].BoundingBox.MinX == results[j].BoundingBox.MinX && results[i].BoundingBox.MinY == results[j].BoundingBox.MinY && results[i].BoundingBox.MaxX == results[j].BoundingBox.MaxX && results[i].BoundingBox.MaxY == results[j].BoundingBox.MaxY) { if (results[i].RecordID.CompareTo(results[j].RecordID) > 0) { Record temp = results[i]; results[i] = results[j]; results[j] = temp; } } else break; } return results; }
public void ExecuteQueryPlan() { List<Record> pooledResults = new List<Record>(1000); Int32 headIndex = 0; StreamReader reader = new StreamReader(QueryPlanFileLocation); StreamWriter qwriter = new StreamWriter(ResultSaveFileLocation + ".q"); StreamWriter iwriter = new StreamWriter(ResultSaveFileLocation + ".i"); StreamWriter dwriter = new StreamWriter(ResultSaveFileLocation + ".d"); StreamWriter uwriter = new StreamWriter(ResultSaveFileLocation + ".u"); Console.WriteLine("Loading Complete"); Cache.FlushCache(); while (!reader.EndOfStream) { PerformanceAnalyzer.ClearStatistics(); String[] values = reader.ReadLine().Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); Int32 queryNumber = Int32.Parse(values[0]); if (queryNumber % 500 == 0) Console.WriteLine(queryNumber.ToString()); if (queryNumber == 5000) break; Char queryType = Char.Parse(values[1]); if (queryType == 'Q') { //writer.WriteLine(); Query query; Char searchType = Char.Parse(values[2]); switch (searchType) { case 'R': { Single x = Single.Parse(values[3]), y = Single.Parse(values[4]), r = Single.Parse(values[5]); query = new RangeQuery(x, y, r*2); //writer.WriteLine("Traditional Range Search"); //writer.WriteLine("Point: ({0:F2},{1:F2})", x, y); //writer.WriteLine("Range: {0:F2}", r); break; } case 'W': { Single x = Single.Parse(values[3]), y = Single.Parse(values[4]), r = Single.Parse(values[5]); query = new WindowQuery(x - r, y - r, x+r, y+r); //writer.WriteLine("Traditional Window Search"); //writer.WriteLine("Lower Point: ({0:F2},{1:F2})", x - r, y - r); //writer.WriteLine("Upper Point: ({0:F2},{1:F2})", x, y); break; } case 'K': { Single x = Single.Parse(values[3]), y = Single.Parse(values[4]); Int32 k = Int32.Parse(values[5]); query = new KNearestNeighborQuery(k, x, y); //writer.WriteLine("Traditional Nearest Neighbor Search"); //writer.WriteLine("Point: ({0:F2},{1:F2})", x, y); //writer.WriteLine("Items: {0}", k); break; } default: continue; } PerformanceAnalyzer.OperationBegan(); List<Record> results = TreeIndex.Search(query); Cache.FlushCache(); while (results.Contains(null)) results.Remove(null); PerformanceAnalyzer.OperationEnded(); //writer.WriteLine("Result Objects:"); foreach (Record result in results) { if (pooledResults.Count >= 1000) pooledResults.RemoveAt(0); pooledResults.Add(result); //writer.WriteLine("{0} {1:F2} {2:F2}", result.RecordID + 1000000 - 1, result.BoundingBox.MinX, result.BoundingBox.MinY); } //writer.WriteLine("Complementary Objects:"); //writer.WriteLine("Statistics"); //writer.WriteLine("Page Loads:\t{0}\tPage Writes:\t{1}\tExecution Time:\t{2}\tCPU Time:\t{3}", PerformanceAnalyzer.PageFaults, PerformanceAnalyzer.PageWrites, PerformanceAnalyzer.ExecutionTime.Ticks, PerformanceAnalyzer.CPUTime.Ticks); qwriter.WriteLine("{0}\t{1}\t{2}\t{3}", PerformanceAnalyzer.PageFaults, PerformanceAnalyzer.PageWrites, PerformanceAnalyzer.ExecutionTime.Ticks, PerformanceAnalyzer.CPUTime.Ticks); } else if (queryType == 'I') { Int32 recordID = Int32.Parse(values[2]); Single x = Single.Parse(values[3]), y = Single.Parse(values[4]); Record recordToInsert = new Record(recordID, new MinimumBoundingBox(x, y, x, y)); PerformanceAnalyzer.OperationBegan(); TreeIndex.Insert(recordToInsert); Cache.FlushCache(); PerformanceAnalyzer.OperationEnded(); //writer.WriteLine(); //writer.WriteLine("Inserting new Record"); //writer.WriteLine("{0}, {1:F2} {2:F2}", recordID + 1000000 - 1, x, y); //writer.WriteLine("Statistics"); //writer.WriteLine("Page Loads:\t{0}\tPage Writes:\t{1}\tExecution Time:\t{2}\tCPU Time:\t{3}", PerformanceAnalyzer.PageFaults, PerformanceAnalyzer.PageWrites, PerformanceAnalyzer.ExecutionTime.Ticks, PerformanceAnalyzer.CPUTime.Ticks); iwriter.WriteLine("{0}\t{1}\t{2}\t{3}", PerformanceAnalyzer.PageFaults, PerformanceAnalyzer.PageWrites, PerformanceAnalyzer.ExecutionTime.Ticks, PerformanceAnalyzer.CPUTime.Ticks); } else if (queryType == 'U') { /*Int32 recordIndex = Int32.Parse(values[2]); if (pooledResults.Count == 0) continue; while (recordIndex >= pooledResults.Count) recordIndex -= pooledResults.Count; Record recordToUpdate = pooledResults[recordIndex]; while (pooledResults.Count > 0 && recordIndex-- > 0) pooledResults.RemoveAt(0); for(int i = 0; i < pooledResults.Count; i++) if(pooledResults[i].RecordID == recordToUpdate.RecordID) pooledResults.RemoveAt(i--); Single x = Single.Parse(values[3]), y = Single.Parse(values[4]); Record updatedRecord = new Record(recordToUpdate.RecordID, new MinimumBoundingBox(x, y, x, y)); if (recordToUpdate.Address.ToString().Equals("18336")) { Console.WriteLine("Updated"); Console.ReadLine(); } PerformanceAnalyzer.OperationBegan(); TreeIndex.Update(recordToUpdate, updatedRecord); Cache.FlushCache(); PerformanceAnalyzer.OperationEnded(); //writer.WriteLine(); //writer.WriteLine("Updating Record"); //writer.WriteLine("From: {0}, {1:F2} {2:F2}", recordToUpdate.RecordID + 1000000 - 1, recordToUpdate.BoundingBox.MinX, recordToUpdate.BoundingBox.MinY); //writer.WriteLine("To: {0}, {1:F2} {2:F2}", updatedRecord.RecordID + 1000000 - 1, x, y); //writer.WriteLine("Statistics"); //writer.WriteLine("Page Loads:\t{0}\tPage Writes:\t{1}\tExecution Time:\t{2}\tCPU Time:\t{3}", PerformanceAnalyzer.PageFaults, PerformanceAnalyzer.PageWrites, PerformanceAnalyzer.ExecutionTime.Ticks, PerformanceAnalyzer.CPUTime.Ticks); uwriter.WriteLine("{0}\t{1}\t{2}\t{3}", PerformanceAnalyzer.PageFaults, PerformanceAnalyzer.PageWrites, PerformanceAnalyzer.ExecutionTime.Ticks, PerformanceAnalyzer.CPUTime.Ticks); */ } else if (queryType == 'D') { /* Int32 recordIndex = Int32.Parse(values[2]); if (pooledResults.Count == 0) continue; while (recordIndex >= pooledResults.Count) recordIndex -= pooledResults.Count; Record recordToDelete = pooledResults[recordIndex]; while (pooledResults.Count > 0 && recordIndex-- > 0) pooledResults.RemoveAt(0); for (int i = 0; i < pooledResults.Count; i++) if (pooledResults[i].RecordID == recordToDelete.RecordID) pooledResults.RemoveAt(i--); if (recordToDelete.Address.ToString().Equals("18336")) { Console.WriteLine("Deleted"); Console.ReadLine(); } PerformanceAnalyzer.OperationBegan(); TreeIndex.Delete(recordToDelete); Cache.FlushCache(); PerformanceAnalyzer.OperationEnded(); //writer.WriteLine(); //writer.WriteLine("Deleted Record"); //writer.WriteLine("{0}, {1:F2} {2:F2}", recordToDelete.RecordID + 1000000 - 1, recordToDelete.BoundingBox.MinX, recordToDelete.BoundingBox.MinY); //writer.WriteLine("Statistics"); //writer.WriteLine("Page Loads:\t{0}\tPage Writes:\t{1}\tExecution Time:\t{2}\tCPU Time:\t{3}", PerformanceAnalyzer.PageFaults, PerformanceAnalyzer.PageWrites, PerformanceAnalyzer.ExecutionTime.Ticks, PerformanceAnalyzer.CPUTime.Ticks); dwriter.WriteLine("{0}\t{1}\t{2}\t{3}", PerformanceAnalyzer.PageFaults, PerformanceAnalyzer.PageWrites, PerformanceAnalyzer.ExecutionTime.Ticks, PerformanceAnalyzer.CPUTime.Ticks); */ } } reader.Close(); qwriter.Close(); iwriter.Close(); dwriter.Close(); uwriter.Close(); }