To construct a node, select from the paint buttons in the lower border of the application. The first node is a source (i.e., generates objects or packets), the second an intermediate connecting node, and the third a sink (i.e., eats objects). You can click on nodes to select the type to be painted, then click on the drawing area to place them. (To remove an element, click on it and then select "Delete Selection" from the Selection menu.)
The black line to the right is a channel. You can draw channels by selecting this element from the lower border, double clicking on a start node, then clicking on another node. Note that channels have directions: they go from the node you start with to the node you end with. It is possible to have more than one channel between two nodes (e.g., one in each direction), but this isn't drawn particularly well.
To start objects moving through the demo, select "Start Simulation" from the Control menu. You can pause the simulation using "Stop Simulation". You can dynamically add elements while the simulation is running. You can also temporally "remove" a node or channel by selecting it and then choosing the "Disable Selection" command from the Selection menu. To re-enable an element, use the "Enable Selection" command. Using the "Delete Selection" option to physically remove an element from the network while the simulation is running is discouraged; deletion is provided only for creating a new network, not for dynamically changing network behavior. Check the fine print for why (link removed, fineprint.html lost).
Experiment with the network for a few minutes. Can you get the channels to fill up? Can you create any other interesting behavior? Remember that you can disable channels (using the menu) while the simulation is running. You may want to keep a record of your experiments to compare your later results with. (Such a record should include both network topology (how things are connected) and dynamic behavior (what you did, what it did).) You can even save any particularly interesting network configurations using the Save Network option under the File menu. When you save networks, be sure to leave the .binsort suffix on their names, as this allows the application to filter out files that could not be the network you want to load. There is fine print on this (link removed, fineprint.html lost).
We have provided two connecting types of nodes. The first, and the one you have been using, is DefaultNodeBehavior. The other is IntermediateNodeBehavior. Can you decern any differences between the two? What, if any, advantages does one enjoy over the other?
Your NodeBehavior class will not be a Runnable; instead it will be called by a Node, which is Runnable and has its own Thread. The Node's run method also contains the while(true) loop. (Node also implements the graphical user interface (GUI) for a node.) The heart of Node's run method looks something like this:
InputChannel[] inputChannels; OutputChannel[] outputChannels;
public void run () { while (true) { this.nodeBehavior.act( this.inputChannels, this.outputChannels ); } }Since act() will be called from inside a while(true) loop, you only have to handle one object at a time.
Note that act takes two arrays as its arguments. The first is an array of input channels. Each of these channels may contain packets ready to be read. Each
InputChannel has
public Object readObject()
throws ChannelEmptyException, ChannelDisabledException;You only need to read one packet from one input channel on each time around the interactive control loop, though. Note that input channels may be empty or disabled, in which case they will throw an appropriate exception.
The second argument to act is an array of output channels. An active non-full output channel would be a good place to put any packet you may have picked up. OutputChannel has
public void writeObject( Object ) throws ChannelFullException, ChannelDisabledException;But be careful: when the output channels are full, they will throw an exception if you try to write to them. Make sure that you don't drop any packets if this happens, or write packets that don't exist.
The main piece of your job is to implement the act method of NodeBehavior. This method should take an object off of one of the inputChannels (using readObject()) and feed it to one of the outputChannels (using writeObject()). Remember that there are potentially several streams of each kind, and that some of these streams may be disabled.
There are several ways that you can choose the input and output channels from their respective arrays. Think of at least two, and record these strategies. The more creative you can be, the more interesting your lab will be. You should design code for at least one of these strategies, and ideally for more than one.
One of the main points of this lab is to observe the effects of different strategies on the behavior of your network as a whole. Is your strategy fair? Does it drop packets? Create them? Do packets cluster in certain parts of your network? Can you come up with a strategy that behaves differently?
Some utilities that you might want to use:
public static int cs101.util.MoreMath.randomInt( int range );returns an int between 0 and range, inclusive. You can refer to it as Math.randomInt if you include the line import cs101.util.*; at the top of your file.
public static void Thread.sleep( int millis ) throws InterruptedException;causes the current Thread to sleep for millis milliseconds. This allows you to put delays in your nodes. Warning: You will have to catch the exception, though you don't necessarily have to do anything with it.
If you have other ideas, design them and then ask us about them.
Begin the lab by implementing a node behavior. You will need to define a new class, say MyClass. What should you call the file it's defined in? What does it need to extend or implement? What methods does it have? (Remember that the interactive control loop is already defined for you, but it expects to be able to call your act method with two arrays.
The first lines of your file, before your class definition, will need to say:
package BinSort;
import BinSort.Exceptions.*;Also, you should be sure that your class is public.
Once your code compiles, you should try running it. To run your code, you will need to supply the name of your node behavior class to BinSort. You can do this by typing
BinSort.Main MyClass(assuming that MyClass is the name of your class, and also that you've already compiled your class using javac.)
You can now test your code using a network you have saved. It is probably best to use a very simple network first -- if you don't have a simple one saved, you might want to create one now.
Once you have this network running, try some others. See if you can find one that stumps your code. (Try to fix it, or at least to understand why. Can you design another network to stump your code?)
Don't forget to tell the course staff about your networks, so that we can use them, too :)
This course is a part of Lynn Andrea Stein's Rethinking CS101 project at the MIT AI Lab and the Department of Electrical Engineering and Computer Science at the Massachusetts Institute of Technology.