/** * If the given name already denotes a file, this opens it; otherwise, this creates a new empty * file. A null name produces a temporary heap file which requires no DB entry. */ public HeapFile(String name) throws ChainException { this.name = name; PageId firstPageId; Page page = new Page(); pages = new ArrayList<PageId>(); pids = new HashSet<Integer>(); if (name == null) { // Temporary heap file firstPageId = global.Minibase.BufferManager.newPage(page, 1); current = new HFPage(page); current.setCurPage(firstPageId); pages.add(firstPageId); pids.add(firstPageId.pid); global.Minibase.BufferManager.unpinPage(firstPageId, true); } else { firstPageId = global.Minibase.DiskManager.get_file_entry(name); if (firstPageId == null) { firstPageId = global.Minibase.BufferManager.newPage(page, 1); global.Minibase.DiskManager.add_file_entry(name, firstPageId); global.Minibase.BufferManager.unpinPage(firstPageId, true); pages.add(firstPageId); pids.add(firstPageId.pid); global.Minibase.BufferManager.pinPage(firstPageId, page, false); recordNumber = 0; current = new HFPage(page); current.setCurPage(firstPageId); global.Minibase.BufferManager.unpinPage(firstPageId, true); return; } // add the new HFPages global.Minibase.BufferManager.pinPage(firstPageId, page, false); // System.err.println("hahahaha"+page.getData()); current = new HFPage(page); current.setData(page.getData()); pages.add(firstPageId); pids.add(firstPageId.pid); recordNumber += amount(current); global.Minibase.BufferManager.unpinPage(firstPageId, false); PageId currentPageId = current.getNextPage(); while (currentPageId.pid != 0 & currentPageId.pid != -1) { HFPage temp = new HFPage(); global.Minibase.BufferManager.pinPage(currentPageId, temp, false); pages.add(currentPageId); pids.add(currentPageId.pid); recordNumber += amount(temp); global.Minibase.BufferManager.unpinPage(currentPageId, false); currentPageId = temp.getNextPage(); } } }
/** * initial the end node set, if the end node is intersect, add it directly or we find the end * node's edge's entrance(s) * * @param nodeId * @return */ public static HashSet<Long> initialEndSet(long nodeId) { HashSet<Long> endSet = new HashSet<Long>(); NodeInfo end = OSMData.nodeHashMap.get(nodeId); // initial start end set if (end.isIntersect()) { endSet.add(nodeId); } else { EdgeInfo edge = end.getOnEdgeList().getFirst(); if (!edge.isOneway()) { endSet.add(edge.getEndNode()); } endSet.add(edge.getStartNode()); } return endSet; }
/** * Searches the directory for a data page with enough free space to store a record of the given * size. If no suitable page is found, this creates a new data page. */ protected PageId getAvailPage(int reclen) { for (int i = 0; i < pages.size(); i++) { PageId pid = pages.get(i); Page page = new Page(); global.Minibase.BufferManager.pinPage(pid, page, false); HFPage hfpage = new HFPage(); hfpage.copyPage(page); if (hfpage.getFreeSpace() >= reclen) { global.Minibase.BufferManager.unpinPage(pid, true); return pid; } global.Minibase.BufferManager.unpinPage(pid, false); } Page page = new Page(); PageId pid = global.Minibase.BufferManager.newPage(page, 1); HFPage hfpage = new HFPage(page); // initialize HFPage hfpage.setCurPage(pid); pages.add(pid); pids.add(pid.pid); current.setNextPage(pid); hfpage.setPrevPage(current.getCurPage()); current = hfpage; global.Minibase.BufferManager.unpinPage(pid, true); return pid; }
/** * Reads a record from the file, given its id. * * @throws IllegalArgumentException if the rid is invalid */ public byte[] selectRecord(RID rid) { PageId pid = rid.pageno; if (!pids.contains(pid.pid)) throw new IllegalArgumentException("the RID is invalid"); Page page = new Page(); global.Minibase.BufferManager.pinPage(pid, page, false); global.Minibase.BufferManager.unpinPage(pid, false); return page.getData(); }
/** * Updates the specified record in the heap file. * * @throws IllegalArgumentException if the rid or new record is invalid */ public void updateRecord(RID rid, byte[] newRecord) { PageId pid = rid.pageno; if (!pids.contains(pid.pid)) throw new IllegalArgumentException("the RID is invalid"); Page page = new Page(); global.Minibase.BufferManager.pinPage(pid, page, false); HFPage hfpage = new HFPage(page); if (newRecord.length != hfpage.selectRecord(rid).length) { throw new IllegalArgumentException("fail to update RID"); } global.Minibase.BufferManager.unpinPage(rid.pageno, false); }
public boolean updateRecord(RID rid, Tuple newTuple) throws ChainException { // TODO Auto-generated method stub PageId pid = rid.pageno; if (!pids.contains(pid.pid)) throw new IllegalArgumentException("the RID is invalid"); Page page = new Page(); global.Minibase.BufferManager.pinPage(pid, page, false); HFPage hfpage = new HFPage(page); if (newTuple.getLength() != hfpage.selectRecord(rid).length) { throw new IllegalArgumentException("fail to update RID"); } global.Minibase.BufferManager.unpinPage(rid.pageno, false); return true; }
/** * Deletes the specified record from the heap file. * * @throws IllegalArgumentException if the rid is invalid */ public boolean deleteRecord(RID rid) { PageId pid = rid.pageno; if (!pids.contains(pid.pid)) throw new IllegalArgumentException("the rid is invalid"); try { Page page = new Page(); global.Minibase.BufferManager.pinPage(pid, page, false); HFPage hfpage = new HFPage(); hfpage.copyPage(page); hfpage.deleteRecord(rid); global.Minibase.BufferManager.unpinPage(pid, true); recordNumber--; return true; } catch (Exception e) { System.err.print("fail to delete record"); return false; } }
/** * Inserts a new record into the file and returns its RID. * * @throws IllegalArgumentException if the record is too large */ public RID insertRecord(byte[] record) throws IllegalArgumentException, ChainException { if (record.length > GlobalConst.MAX_TUPSIZE) throw new IllegalArgumentException("the record's size is too large"); for (int i = 0; i < pages.size(); i++) { PageId pid = pages.get(i); Page page = new Page(); global.Minibase.BufferManager.pinPage(pid, page, false); HFPage hfpage = new HFPage(page); hfpage.setCurPage(pid); hfpage.setData(page.getData()); if (hfpage.getFreeSpace() > record.length) { RID rid = hfpage.insertRecord(record); recordNumber++; global.Minibase.BufferManager.unpinPage(pid, true); return rid; } global.Minibase.BufferManager.unpinPage(pid, false); } Page page = new Page(); PageId pid = global.Minibase.BufferManager.newPage(page, 1); HFPage hfpage = new HFPage(page); // initialize HFPage hfpage.initDefaults(); hfpage.setCurPage(pid); // hfpage.print(); RID rid = hfpage.insertRecord(record); pages.add(pid); pids.add(pid.pid); hfpage.setNextPage(pid); hfpage.setPrevPage(current.getCurPage()); current = hfpage; global.Minibase.BufferManager.unpinPage(pid, true); // hfpage.print(); // System.out.println ("The PID is "+pid); recordNumber++; return rid; }
/** * routing using A* algorithm with fibonacci heap basically same as routingAStar function * * @param startNode * @param endNode * @param startTime * @param pathNodeList return path * @return */ public static double routingAStarFibonacci( long startNode, long endNode, int startTime, int dayIndex, ArrayList<Long> pathNodeList) { System.out.println("start finding the path..."); int debug = 0; double totalCost = -1; try { // test store transversal nodes // HashSet<Long> transversalSet = new HashSet<Long>(); if (!OSMData.nodeHashMap.containsKey(startNode) || !OSMData.nodeHashMap.containsKey(endNode)) { System.err.println("cannot find start or end node!"); return -1; } if (startNode == endNode) { System.out.println("start node is the same as end node."); return 0; } HashSet<Long> closedSet = new HashSet<Long>(); HashMap<Long, FibonacciHeapNode<NodeInfoHelper>> nodeHelperCache = new HashMap<Long, FibonacciHeapNode<NodeInfoHelper>>(); FibonacciHeap<NodeInfoHelper> openSet = initialStartSet(startNode, endNode, nodeHelperCache); HashSet<Long> endSet = initialEndSet(endNode); NodeInfoHelper current = null; FibonacciHeapNode<NodeInfoHelper> fCurrent = null; while (!openSet.isEmpty()) { // remove current from openset fCurrent = openSet.min(); openSet.removeMin(); current = fCurrent.getData(); // if(!transversalSet.contains(current.getNodeId())) // transversalSet.add(current.getNodeId()); long nodeId = current.getNodeId(); // add current to closedset closedSet.add(nodeId); if (endSet.contains(nodeId)) { // find the destination current = current.getEndNodeHelper(endNode); totalCost = current.getCost(); break; } // for time dependent routing int timeIndex = startTime + (int) (current.getCost() / OSMParam.SECOND_PER_MINUTE / OSMRouteParam.TIME_INTERVAL); if (timeIndex > OSMRouteParam.TIME_RANGE - 1) // time [6am - 9 pm], we regard times after 9pm as constant edge weights timeIndex = OSMRouteParam.TIME_RANGE - 1; LinkedList<ToNodeInfo> adjNodeList = OSMData.adjListHashMap.get(nodeId); if (adjNodeList == null) continue; // this node cannot go anywhere double arriveTime = current.getCost(); // for each neighbor in neighbor_nodes(current) for (ToNodeInfo toNode : adjNodeList) { debug++; long toNodeId = toNode.getNodeId(); int travelTime; if (toNode.isFix()) // fix time travelTime = toNode.getTravelTime(); else // fetch from time array travelTime = toNode.getSpecificTravelTime(dayIndex, timeIndex); // tentative_g_score := g_score[current] + dist_between(current,neighbor) double costTime = arriveTime + (double) travelTime / OSMParam.MILLI_PER_SECOND; // tentative_f_score := tentative_g_score + heuristic_cost_estimate(neighbor, goal) double heuristicTime = estimateHeuristic(toNodeId, endNode); double totalCostTime = costTime + heuristicTime; // if neighbor in closedset and tentative_f_score >= f_score[neighbor] if (closedSet.contains(toNodeId) && nodeHelperCache.get(toNodeId).getData().getTotalCost() <= totalCostTime) { continue; } NodeInfoHelper node = null; FibonacciHeapNode<NodeInfoHelper> fNode = null; // if neighbor not in openset or tentative_f_score < f_score[neighbor] if (!nodeHelperCache.containsKey(toNodeId)) { // neighbor not in openset // create new one node = new NodeInfoHelper(toNodeId); node.setCost(costTime); node.setHeuristic(heuristicTime); node.setParentId(nodeId); fNode = new FibonacciHeapNode<NodeInfoHelper>(node); openSet.insert(fNode, node.getTotalCost()); nodeHelperCache.put(node.getNodeId(), fNode); } else if (nodeHelperCache.get(toNodeId).getData().getTotalCost() > totalCostTime) { // neighbor in openset fNode = nodeHelperCache.get(toNodeId); node = fNode.getData(); // update information node.setCost(costTime); node.setHeuristic(heuristicTime); node.setParentId(nodeId); if (closedSet.contains(toNodeId)) { // neighbor in closeset closedSet.remove(toNodeId); // remove neighbor form colseset openSet.insert(fNode, node.getTotalCost()); } else { // neighbor in openset, decreaseKey openSet.decreaseKey(fNode, node.getTotalCost()); } } } } if (totalCost != -1) { long traceNodeId = current.getNodeId(); pathNodeList.add(traceNodeId); // add end node traceNodeId = current.getParentId(); while (traceNodeId != 0) { pathNodeList.add(traceNodeId); // add node fCurrent = nodeHelperCache.get(traceNodeId); current = fCurrent.getData(); traceNodeId = current.getParentId(); } Collections.reverse(pathNodeList); // reverse the path list System.out.println("find the path successful!"); } else { System.out.println("can not find the path!"); } // OSMOutput.generateTransversalNodeKML(transversalSet, nodeHashMap); } catch (Exception e) { e.printStackTrace(); System.err.println( "tdsp: debug code " + debug + ", start node " + startNode + ", end node " + endNode); } return totalCost; }
public boolean isNodeInReverseSet(long node) { if (coveredReverseSet.contains(node)) return true; else return false; }
public void addReverseNode(long node) { coveredReverseSet.add(node); }
@Override public void run() { // TODO Auto-generated method stub PriorityQueue<NodeInfoHelper> openSet = new PriorityQueue<NodeInfoHelper>( 10000, new Comparator<NodeInfoHelper>() { public int compare(NodeInfoHelper n1, NodeInfoHelper n2) { return (int) (n1.getTotalCost() - n2.getTotalCost()); } }); HashSet<Long> closedSet = new HashSet<Long>(); initialEndSet(startNode, endNode, openSet, nodeHelperCache); NodeInfoHelper current = null; // HashSet<Long> transversalSet = new HashSet<Long>(); while (!openSet.isEmpty()) { // remove current from openset current = openSet.poll(); long nodeId = current.getNodeId(); // transversalSet.add(nodeId); // add current to closedset closedSet.add(nodeId); // check if forward searching finish if (sharingData.isSearchingFinish()) break; // add to reverse cover nodes, only add the nodes on the highway if (current.getCurrentLevel() == 1) sharingData.addReverseNode(nodeId); NodeInfo fromNodeInfo = OSMData.nodeHashMap.get(nodeId); LinkedList<ToNodeInfo> adjNodeList = adjListHashMap.get(nodeId); if (adjNodeList == null) continue; // this node cannot go anywhere double arriveTime = current.getCost(); // for each neighbor in neighbor_nodes(current) for (ToNodeInfo toNode : adjNodeList) { long toNodeId = toNode.getNodeId(); NodeInfo toNodeInfo = OSMData.nodeHashMap.get(toNodeId); EdgeInfo edgeInfo = fromNodeInfo.getEdgeFromNodes(toNodeInfo); // check if "highway" not found in param, add it // String highway = edgeInfo.getHighway(); int level = 10; if (OSMData.hierarchyHashMap.containsKey(edgeInfo.getHighway())) level = OSMData.hierarchyHashMap.get(edgeInfo.getHighway()); // 1) always level up, e.g. currently in primary, never go secondary // if(level > current.getCurrentLevel()) { // do not level down // continue; // } // 2) keep on highway if (current.getCurrentLevel() == 1 && level > 1) { continue; } int travelTime = toNode.getMinTravelTime(); // tentative_g_score := g_score[current] + dist_between(current,neighbor) double costTime = arriveTime + (double) travelTime / OSMParam.MILLI_PER_SECOND; // tentative_f_score := tentative_g_score + heuristic_cost_estimate(neighbor, goal) double heuristicTime = OSMRouting.estimateHeuristic(toNodeId, endNode); double totalCostTime = costTime + heuristicTime; // if neighbor in closedset and tentative_f_score >= f_score[neighbor] if (closedSet.contains(toNodeId) && nodeHelperCache.get(toNodeId).getTotalCost() <= totalCostTime) { continue; } NodeInfoHelper node = null; // if neighbor not in openset or tentative_f_score < f_score[neighbor] if (!nodeHelperCache.containsKey(toNodeId)) { // neighbor not in openset node = new NodeInfoHelper(toNodeId); nodeHelperCache.put(node.getNodeId(), node); } else if (nodeHelperCache.get(toNodeId).getTotalCost() > totalCostTime) { // neighbor in openset node = nodeHelperCache.get(toNodeId); if (closedSet.contains(toNodeId)) { // neighbor in closeset closedSet.remove(toNodeId); // remove neighbor form colseset } else { openSet.remove(node); } } // neighbor need update if (node != null) { node.setCost(costTime); node.setHeuristic(heuristicTime); node.setCurrentLevel(level); node.setParentId(nodeId); openSet.offer(node); // add neighbor to openset again } } } // OSMOutput.generateTransversalNodeKML(transversalSet, nodeHashMap, "reverse_transversal"); }
@Override public void run() { HashSet<Long> closedSet = new HashSet<Long>(); PriorityQueue<NodeInfoHelper> openSet = OSMRouting.initialStartSet(startNode, endNode, startTime, dayIndex, nodeHelperCache); NodeInfoHelper current = null; // test // HashSet<Long> transversalSet = new HashSet<Long>(); while (!openSet.isEmpty()) { // remove current from openset current = openSet.poll(); long nodeId = current.getNodeId(); // transversalSet.add(nodeId); // add current to closedset closedSet.add(nodeId); // check reverse searching covering nodes if (sharingData.isNodeInReverseSet(nodeId)) { // we found a path, stop here sharingData.addIntersect(nodeId); if (sharingData.isSearchingFinish()) break; else continue; } NodeInfo fromNodeInfo = OSMData.nodeHashMap.get(nodeId); // for time dependent routing in forwarding search int timeIndex = startTime + (int) (current.getCost() / OSMParam.SECOND_PER_MINUTE / OSMRouteParam.TIME_INTERVAL); if (timeIndex > OSMRouteParam.TIME_RANGE - 1) // time [6am - 9 pm], we regard times after 9pm as constant edge weights timeIndex = OSMRouteParam.TIME_RANGE - 1; LinkedList<ToNodeInfo> adjNodeList = adjListHashMap.get(nodeId); if (adjNodeList == null) continue; // this node cannot go anywhere double arriveTime = current.getCost(); // for each neighbor in neighbor_nodes(current) for (ToNodeInfo toNode : adjNodeList) { long toNodeId = toNode.getNodeId(); NodeInfo toNodeInfo = OSMData.nodeHashMap.get(toNodeId); EdgeInfo edgeInfo = fromNodeInfo.getEdgeFromNodes(toNodeInfo); // check if "highway" not found in param, add it // String highway = edgeInfo.getHighway(); int level = 10; if (OSMData.hierarchyHashMap.containsKey(edgeInfo.getHighway())) level = OSMData.hierarchyHashMap.get(edgeInfo.getHighway()); // 1) always level up, e.g. currently in primary, never go secondary // if(level > current.getCurrentLevel()) { // do not level down // continue; // } // 2) keep on highway if (current.getCurrentLevel() == 1 && level > 1) { continue; } int travelTime; // forward searching is time dependent if (toNode.isFix()) // fix time travelTime = toNode.getTravelTime(); else // fetch from time array travelTime = toNode.getSpecificTravelTime(dayIndex, timeIndex); // tentative_g_score := g_score[current] + dist_between(current,neighbor) double costTime = arriveTime + (double) travelTime / OSMParam.MILLI_PER_SECOND; // tentative_f_score := tentative_g_score + heuristic_cost_estimate(neighbor, goal) double heuristicTime = OSMRouting.estimateHeuristic(toNodeId, endNode); double totalCostTime = costTime + heuristicTime; // if neighbor in closedset and tentative_f_score >= f_score[neighbor] if (closedSet.contains(toNodeId) && nodeHelperCache.get(toNodeId).getTotalCost() <= totalCostTime) { continue; } NodeInfoHelper node = null; // if neighbor not in openset or tentative_f_score < f_score[neighbor] if (!nodeHelperCache.containsKey(toNodeId)) { // neighbor not in openset node = new NodeInfoHelper(toNodeId); nodeHelperCache.put(node.getNodeId(), node); } else if (nodeHelperCache.get(toNodeId).getTotalCost() > totalCostTime) { // neighbor in openset node = nodeHelperCache.get(toNodeId); if (closedSet.contains(toNodeId)) { // neighbor in closeset closedSet.remove(toNodeId); // remove neighbor form colseset } else { openSet.remove(node); } } // neighbor need update if (node != null) { node.setCost(costTime); node.setHeuristic(heuristicTime); node.setCurrentLevel(level); node.setParentId(nodeId); openSet.offer(node); // add neighbor to openset again } } } // test // OSMOutput.generateTransversalNodeKML(transversalSet, "forward_transversal"); }