我正在开发一个项目来模拟到达和离开虚拟内存的内存段。当段离开,或者内存未被占用时,它将成为洞。
约束:
问题:在两个节点之间插入节点时,我陷入了循环循环。我一直试图保持“先前”和“当前”节点,但没有成功
而不是列表如下:Node0 -> Node1 -> Node2
它显示Node0 ->Node2
,其中Node1是要插入的节点。
输出:
|位置|尺寸|离开的时间|
尝试解决方案:我创建了一个先前和当前节点以在其间插入节点。搜索必须从最后一个节点开始; lastPlacement
。我在上面评论了我认为触发错误的部分。
下面的整个代码, place方法中发生错误。
运行时使用的测试文件:
N
R 1000 5 100 80 10000
P
E
/********************************************************************************
* @author Evan Bechtol (ecb120030)
* <h1>Project: Memory Segmentation Simulation</h1>
* <p>Simulation of arrivals/departures/placements of segments in a
* segmented virtual memory, through the use of a linked-list. Implements a
* next-fit policy. Constraints: There can never be neighboring holes.</p>
* @since 2015-2-13
* @see http://www.programmingsimplified.com/java/source-code/java-program-to-bubble-sort
* @see http://web.cerritos.edu/jwilson/SitePages/java_language_resources/Java_printf_method_quick_reference.pdf
* @see http://www.algolist.net/Data_structures/Singly-linked_list/Removal
* @see http://crunchify.com/a-simple-singly-linked-list-implementation-in-java/
*
********************************************************************************/
import java.util.*;
import java.io.*;
/**
* Creates nodes to be used as data containers in the Memory class
*/
class Node {
boolean segment; // Equals false if this Node represents a hole
int location; // Position in memory of first byte
int size; // Size that node occupies
int timeToDepart; // Only valid when this Node represents a segment
Node next;
/**
* Constructor for generating a segment in memory
*
* @param locn location of node to be created
* @param sz size of node to be created
* @param endOfLife the timeOfDay node is to depart
* @param nxt specifies the next node to reference in the list
*/
Node (int locn, int sz, int endOfLife, Node nxt) {
segment = true;
location = locn;
size = sz;
timeToDepart = endOfLife;
next = nxt;
}
/**
* Constructor for a hole
*
* @param locn location of hole to be created
* @param sz size of hole to be created
* @param nxt reference to next node in the list
*/
Node (int locn, int sz, Node nxt) {
segment = false;
location = locn;
size = sz;
next = nxt;
}
} // End Node class
/**
* Creates a linked-list of ndoes to simulate virtual memory segments and holes
*/
class Memory {
private static int memorySize; // Defines the total size for the memory
Node head; // Refers to first node in memory
Node lastPlacement; // Refers to the last node that was placed, or hole if the last placed segment is removed
/**
* Constructor for Memory, generates a single hole Node of the given size
*
* @param size initial size of memory object
*/
Memory (int size) {
memorySize = size;
Node n = new Node (0, memorySize, null);
lastPlacement = head = n;
}
/**
* Attempts to place a request using the Next Fit Policy. Returns false if there
* isn't a hole big enough. Prints a confirmation if placed; return true
*
* @param size size of placement to be made
* @param timeOfDay the time at which the placement is being made
* @param lifeTime how long the segment is to remain in memory
* @param verbose specifies if extra placement information is to be given
* @return boolean: returns true if the placement was successful
*/
boolean place (int size, int timeOfDay, int lifeTime, boolean verbose) {
// If the list is empty, we can place as head node
if (isEmpty()) {
Node current = new Node (0, size, 0, null);
lastPlacement = head = current;
return true;
}
// There are nodes in the list
else {
Node current = lastPlacement; // We start searching for a hole at our lastPlacement
Node previous = head;
// While there are still nodes to reverse, keep looking
while (current != null) {
// If we are looking at a hole and it is equal to, or larger than our required size
if ((!current.segment) && (current.size >= size)) {
// Hole is EXACT size required
if (current.size == size) {
current.segment = true;
current.timeToDepart = timeOfDay + lifeTime;
}
// Hole is larger than our size required
else {
Node newNode = new Node (current.location, size, timeOfDay + lifeTime, current); //timeOfDay + lifeTime = timeToDepart
current.location += size + 1;
current.size -= size;
lastPlacement = newNode;
previous.next = newNode;
if (newNode.location == 0) {
head = newNode;
}
}
/* newNode.segment = true;
current.next = newNode;
current.size = current.size - size; // Adjust size of hole after placing segment
lastPlacement = newNode;*/
// If verbose == true, print the confirmation
if (verbose) {
System.out.println ("Segment at location: " + lastPlacement.location + "\twith size: " + lastPlacement.size + "\tdeparts at: " + lastPlacement.timeToDepart);
}
return true;
}
previous = current;
current = current.next;
} // End while
current = head; // To traverse from start of list
//While there are still nodes to reverse, keep looking
while (current != lastPlacement) {
// If we are looking at a hole
if ((!current.segment) && (current.size >= size)) {
// Hole is EXACT size required
if (current.size == size) {
current.segment = true;
current.timeToDepart = timeOfDay + lifeTime;
}
// Hole is larger than our size required
else {
// If the hole is larger or equal to the size we need
Node newNode = new Node (current.location, size, timeOfDay + lifeTime, current); //timeOfDay + lifeTime = timeToDepart
current.location += size + 1;
current.size -= size;
lastPlacement = newNode;
previous.next = newNode;
if (newNode.location == 0) {
head = newNode;
}
}
/* newNode.segment = true;
current.next = newNode;
current.size = current.size - size;
lastPlacement = newNode;*/
// If verbose == true, print the confirmation
if (verbose) {
System.out.println ("Placed segment at location: " + lastPlacement.location + "\twith size: " + lastPlacement.size + "\tdeparts at: " + lastPlacement.timeToDepart);
}
return true;
}
previous = current;
current = current.next;
} // End while
}
// If we reach this point, segment could not be placed
return false;
}
/**
* Remove segments from the list, which are ready to depart.
* <p>Checks the following conditions:<ul><li>
* 1) Head is segment and ready to depart
* 2) Current is segment and ready to depart
* 3) Previous is hole, current is hole
* 4) We are combining the node containing last placement, with another node</li></ul></p>
*
* @param timeOfDay time at which the removal is being done
*/
void removeSegmentsDueToDepart (int timeOfDay) {
// Case 1: Head is segment and ready to depart
if ((head.segment) && (head.timeToDepart <= timeOfDay)) {
head.segment = false; // Allow node to become a hole
//System.out.println ("Case 1.");
}
// Create reference to head node
Node previous = head;
// Begin iterating on list from 2nd node
while (previous.next != null) {
//Use this as our current position
Node current = previous.next;
// Case 2: Current is segment and ready to depart
if ((current.segment) && (current.timeToDepart <= timeOfDay)) {
//Combine
current.segment = false;
//System.out.println ("Case 2.");
}
// Case 3: previous is hole, current is hole
if ((!previous.segment) && (!current.segment)) {
// Case 4: We are combining the node containing last placement, with another node
if (current == lastPlacement) {
// Set last placement to the node to be combined to
lastPlacement = previous;
//System.out.println ("Case 4.");
}
// Combine
previous.size += current.size;
previous.next = current.next;
}
// Else we adjust our position.
else {
previous = current;
}
} // End while
}
/**
* Print a 3-column tab-separated list of all segments in Memory.
* Displayed in ascending order of location.
*/
void printLayout() {
Node current;
// Print the sorted array of nodes
for (current = head; current != null; current = current.next) {
System.out.println (current.location + "\t" + current.size + "\t" + current.timeToDepart);
}
}
/**
* Determines the empty or occupied state of the list
*
* @return Returns true if list is empty
* @return Returns false if nodes are in the list
*/
public boolean isEmpty () {
if (head == null) {
return true;
}
return false;
}
} // End Memory class
/**
* Class to test Memory and Node classes. Accepts file-redirection from commandline by using the
* scanner with System.in, can also accept file input by using scanner with new File
*/
public class EVBEP1 {
/**
* Used to test implementation of Memory and Node objects. Processes commands received through
* either the commandline or file-input.
*
* @param args Standard parameter for parsing commands received
* @throws FileNotFoundException If file is unable to be located, exception is thrown
*/
public static void main(String[] args) throws FileNotFoundException {
// Used for accepting command line arguments
//Scanner sc = new Scanner (System.in);
// Used for testing purposes
Scanner sc = new Scanner(new File("p115sd5.txt"));
String line = "";
boolean done = false;
Memory memory = new Memory(0); // Memory object
int timeOfDay = 0; // Simulated wall clock, begins with value zero
int placements = 0; // Number of placements completed, begins with value zero
long totalSpaceTime = 0; // Sum of placed segmentSize(i) x segmentLifetime(i)
float meanOccupancy = 0;
// Loop runs as long as done != true
while (!done) {
line = sc.nextLine(); // Store data gathered from file into String
String [] tokens = line.split(" "); // Split the string using space as delimiter
// Switch for processing commands received
switch (tokens[0]) {
// Print name followed by newline
case "N": {
System.out.println("Evan Clay Bechtol");
break;
}
// Create a memory object of size s
case "C": {
memory = new Memory(Integer.parseInt(tokens[1])); // Create a new Memory object
break;
}
// End of data file, print newline and exit
case "E": {
System.out.println();
done = true; // Break the loop, end the program
break;
}
// Add segment of size 'u' and lifetime 'v' and print confirmation record
case "A": {
int size = Integer.parseInt(tokens[1]);
int lifeTime = Integer.parseInt(tokens[2]);
timeOfDay++;
memory.removeSegmentsDueToDepart(timeOfDay);
// Boolean controls whether confirmation is printed.
while (!memory.place(size, timeOfDay, lifeTime, true)) {
timeOfDay++;
memory.removeSegmentsDueToDepart(timeOfDay);
} // End while
placements++;
// Print confirmation message
System.out.printf("Segment of size %4d", size);
System.out.printf("\tplaced at time %4d", timeOfDay);
System.out.printf("\tat location %4d", memory.lastPlacement.location);
System.out.printf("\tdeparts at %4d", memory.lastPlacement.timeToDepart);
System.out.println();
break;
}
// Print the current segments in the list
case "P": {
System.out.println ();
memory.printLayout();
break;
}
case "R": {
int size = Integer.parseInt(tokens[1]); // Size
memory = new Memory(size);
int minSegSize = Integer.parseInt(tokens[2]); // Minimum seg. size
int maxSegSize = Integer.parseInt(tokens[3]); // Maximum seg. size
int maxLifeTime = Integer.parseInt(tokens[4]); // Maximum lifetime of segs.
int numSegs = Integer.parseInt(tokens[5]); // Number of segs. to simulate
timeOfDay = 0;
placements = 0;
Random ran = new Random (); // "Random" number generator
Scanner n = new Scanner (System.in);
while (placements < numSegs) {
//System.out.println ("Press any key to iterate.. Placements made: " + placements);
memory.printLayout();
//System.out.println ("Loc: " + memory.lastPlacement.location + "\tSize: " + memory.lastPlacement.size + "\tdeparts at: " + memory.lastPlacement.timeToDepart);
/*if( memory.lastPlacement.next != null) {
System.out.println ("Next)" + " Loc: " + memory.lastPlacement.next.location + "\tSize: " + memory.lastPlacement.next.size + "\tdeparts at: " + memory.lastPlacement.next.timeToDepart);
}
else {
System.out.println ("Next = null");
}*/
//n.nextLine();
timeOfDay++;
memory.removeSegmentsDueToDepart(timeOfDay);
int newSegSize = minSegSize + ran.nextInt(maxSegSize - minSegSize + 1);
int newSegLifetime = 1 + ran.nextInt(maxLifeTime);
totalSpaceTime += newSegSize * newSegLifetime;
while (!memory.place(newSegSize, timeOfDay, newSegLifetime, false)) {
timeOfDay++;
memory.removeSegmentsDueToDepart(timeOfDay);
} // End while
placements++;
} // End while
// Print final summary of execution
meanOccupancy = totalSpaceTime / (timeOfDay);
System.out.printf ("Number of placements made = %6d", placements);
System.out.println();
System.out.printf ("Mean occupancy of memory = %8.2f", meanOccupancy);
System.out.println();
n.close();
break;
}
} // End switch
} // End while
sc.close();
} // End main
} // End EVBEP1 class
答案 0 :(得分:0)
我通过将place方法调整为以下内容来解决问题:
boolean place (int size, int timeOfDay, int lifeTime, boolean verbose) {
// If the list is empty, we can place as head node
if (isEmpty()) {
Node current = new Node (0, size, -1, null);
lastPlacement = head = current;
return true;
}
// There are nodes in the list
else {
Node current = lastPlacement; //We start searching for a hole at our lastPlacement
//While there are still nodes to reverse, keep looking
while (current != null) {
// If we are looking at a hole
if (!current.segment && current.timeToDepart <= timeOfDay) {
if (current.size == size) {
current.segment = true;
current.timeToDepart = timeOfDay + lifeTime;
}
// If the hole is larger or equal to the size we need
if (current.size > size) {
Node n = new Node (current.location, size, timeOfDay + lifeTime, current.next); //timeOfDay + lifeTime = timeToDepart
n.segment = true;
current.next = n;
current.size = current.size - size; // Adjust size of hole after placing segment
lastPlacement = current = n;
// If verbose == true, print the confirmation
if (verbose) {
System.out.println ("Segment at location: " + lastPlacement.location + "\twith size: " + lastPlacement.size + "\tdeparts at: " + lastPlacement.timeToDepart);
}
return true;
}
}
current = current.next;
} // End while
current = this.head; // To traverse from start of list
//While there are still nodes to reverse, keep looking
while (current != lastPlacement) {
// If we are looking at a hole
if (!current.segment && current.timeToDepart <= timeOfDay) {
if (current.size == size) {
current.segment = true;
current.timeToDepart = timeOfDay + lifeTime;
}
// If the hole is larger or equal to the size we need
if (current.size > size) {
Node n = new Node (current.location + size, size, timeOfDay + lifeTime, current.next); //timeOfDay + lifeTime = timeToDepart
n.segment = true;
current.next = n;
current.size = current.size - size;
lastPlacement = current = n;
// If verbose == true, print the confirmation
if (verbose) {
System.out.println ("Segment at location: " + lastPlacement.location + "\twith size: " + lastPlacement.size + "\tdeparts at: " + lastPlacement.timeToDepart);
}
return true;
}
}
current = current.next;
} // End while
}
// If we reach this point, segment could not be placed
return false;
}