目录
Abstract
Introduction
Topic
The topic of project 5-7 is concurrent elevator simulation. The program read requests from stdin, simulate the elevator system, and print runtime infomation to stdout.
Request
<PersonID>-FROM-<FromLevel>-TO-<ToLevel>
- On behalf of a pessenger
-
<PersonID>
must be unique
Elevator
- Function
- Move: Move up or down to next level in
<MoveTime>
, and printARRIVE-<Level>-<ElevatorName>
- Open Door: Open Door in
<OpenTime>
, and printOPEN-<Level>-<ElevatorName>
when begin opening - Close Door: Close Door in
<CloseTime>
, and printCLOSE-<Level>-<ElevatorName>
when close finished - Pessenger in: Print
IN-<PersonID>-<Level>-<ElevatorName>
- Pessenger out: Print
OUT-<PersonID>-<Level>-<ElevatorName>
- Move: Move up or down to next level in
- Argument
- Name
- Time
- OpenTime
- CloseTime
- MoveTime
- Level
- InitialLevel
- SupLevel
- InfLevel
- ApprovedLevel
- Capacity
Analysis
The major focus is concurrency: The program has to plan and simulate while reading requests, so it has to be concurrent. Thus we have to design a concurrent architechture and guarantee its thread safety.
Also, for multi-elevator scene, we need to design a coordinating thread to coordinate elevators.
The program's function can be classified as follows, and the threads can be designed correspondingly:
Reading Requests
Reading requests in real time, and pass them to coordinating thread.
Coordinating
Get requests from reading thread, set path for the person and pass it to scheduling thread.
Scheduling and controling
Get requests from reading thread, schedule and pass the action of elevator to elevator, and control the movement of passenger.
Elevator simulation
Get command from scheduling thread, open and close door, and go up or down stairs.
Course
This topic has three assignments.
P5-P6
Reading (and coordinating)
- Read from given input interface
- Analyse the request, put the person to corresponse location in concurrent two-dimensional map
- Dimension 1: From level
- Dimension 2: To level
- Pass person to scheduling and controling thread through cuncurrent map:
ConcurrentHashMap<MapKey, Set<Integer>>
Scheduling and controling
- Move up and down again and again
- Take in person whose destination direction is consistent with the elevator
- Free person who arrived
- U-turn if there's no person ahead
- Stop if there's no person anywhere
- Give command through
TransferQueue<Command>
to elevator
Elevator simulation
- Execute command
- Print information
- Change level
- Sleep for given time
P7
Reading and coordinating
- Read from given input interface
- Analyse and coordinate
- If there's a single elevator approved to access both from and to floor
- The person only have one request: from
<FromLevel>
to<ToLevel>
- The person only have one request: from
- else
- Because it takes at most two steps to go from
<FromLevel>
to<ToLevel>
- Find the elevator who can access
<FromLevel>
- Find the elevator who can access
<ToLevel>
- Find the level which can be accessed by both elevator
- The person has two request
- From
<FromLevel>
to<TransferLevel>
- From
<TransgerLevel>
to<ToLevel>
- From
- Because it takes at most two steps to go from
- The coordinate algorithm can be refacted to recursive one to support any number of transfers
- If there's a single elevator approved to access both from and to floor
- Pass
- Pass person to scheduling and controling thread through cuncurrent map:
ConcurrentHashMap<MapKey, Set<Integer>>
- The mapkey presents the first request:
new MapKey(<FromLevel>, <ToLevel>)
- The rest requests stored in the person object
- Pass person to scheduling and controling thread through cuncurrent map:
Scheduling and controling
- Move up and down again and again
- If current level is accessable
- Take in person
- Destination direction is consistent with the elevator
- Destination level is accessable
- Free person who arrived
- If the person has rest requests, put him to correspensive location in reqMap, and delete its next request
- Take in person
- U-turn if there's no person at accessable level ahead
- Stop if there's no person anywhere
- If current level is accessable
- Give command through
TransferQueue<Command>
to elevator
Elevator simulation
- Execute command
- Print information
- Change level
- Sleep for given time
Class Design
Measurement
Complexity Metric
Method Complexity
Method | ev(G) | iv(G) | v(G) |
---|---|---|---|
com.nyan.EleSysTest.main(String[]) | 1 | 1 | 1 |
com.nyan.elesys.Commander.Commander(int,String,Integer[],Integer,Integer,Integer,ConcurrentHashMap<MapKey, Set<Person>>,Long,Long,Long) |
1 | 1 | 1 |
com.nyan.elesys.Commander.closeDoor() | 1 | 2 | 2 |
com.nyan.elesys.Commander.downHave() | 3 | 2 | 3 |
com.nyan.elesys.Commander.inDownPsgers() | 1 | 3 | 3 |
com.nyan.elesys.Commander.inPsgers(Integer) | 4 | 4 | 5 |
com.nyan.elesys.Commander.inUpPsgers() | 1 | 3 | 3 |
com.nyan.elesys.Commander.levelHave(int) | 5 | 6 | 8 |
com.nyan.elesys.Commander.loop() | 7 | 5 | 9 |
com.nyan.elesys.Commander.openDoor() | 1 | 2 | 2 |
com.nyan.elesys.Commander.outPsgers() | 1 | 4 | 4 |
com.nyan.elesys.Commander.run() | 1 | 4 | 5 |
com.nyan.elesys.Commander.upHave() | 3 | 2 | 3 |
com.nyan.elesys.Coordinator.Coordinator(ConcurrentHashMap<MapKey, Set<Person>>,Integer[][]) |
1 | 2 | 2 |
com.nyan.elesys.Coordinator.run() | 12 | 11 | 14 |
com.nyan.elesys.Elevator.Elevator(Long,Long,Long,Integer,String,TransferQueue<Command>) |
1 | 1 | 1 |
com.nyan.elesys.Elevator.getLevelNum() | 1 | 1 | 1 |
com.nyan.elesys.Elevator.run() | 3 | 7 | 8 |
com.nyan.elesys.Level.Level(Integer) | 1 | 1 | 1 |
com.nyan.elesys.Level.add(Integer) | 1 | 2 | 2 |
com.nyan.elesys.Level.addOne() | 1 | 1 | 2 |
com.nyan.elesys.Level.equals(Object) | 2 | 2 | 2 |
com.nyan.elesys.Level.getLevelNum() | 1 | 1 | 1 |
com.nyan.elesys.Level.sub(Integer) | 1 | 2 | 2 |
com.nyan.elesys.Level.subOne() | 1 | 1 | 2 |
com.nyan.elesys.Level.toString() | 1 | 1 | 1 |
com.nyan.elesys.MapKey.MapKey(Integer,Integer) | 1 | 1 | 1 |
com.nyan.elesys.MapKey.equals(Object) | 2 | 3 | 3 |
com.nyan.elesys.MapKey.hashCode() | 1 | 1 | 1 |
com.nyan.elesys.MapKey.toString() | 1 | 1 | 1 |
com.nyan.elesys.Person.Person(Integer) | 1 | 1 | 1 |
com.nyan.elesys.Person.addReq(Request) | 1 | 1 | 1 |
com.nyan.elesys.Person.compareTo(Person) | 1 | 1 | 1 |
com.nyan.elesys.Person.nextReq() | 2 | 1 | 2 |
com.nyan.elesys.Person.toString() | 1 | 1 | 1 |
com.nyan.elesys.PsgsList.PsgsList(Integer,Integer) | 1 | 2 | 2 |
com.nyan.elesys.PsgsList.add(int,Set<Person>) |
1 | 1 | 1 |
com.nyan.elesys.PsgsList.get(int) | 1 | 1 | 1 |
com.nyan.elesys.PsgsList.getTotal() | 1 | 2 | 2 |
com.nyan.elesys.PsgsList.isEmpty() | 3 | 3 | 4 |
com.nyan.elesys.Request.Request(Integer,Integer) | 1 | 1 | 1 |
com.nyan.elesys.Request.getFromLevel() | 1 | 1 | 1 |
com.nyan.elesys.Request.getToLevel() | 1 | 1 | 1 |
Class Complexity
Class | OCavg | WMC |
---|---|---|
com.nyan.EleSysTest | 1 | 1 |
com.nyan.elesys.Command | n/a | 0 |
com.nyan.elesys.Commander | 3.33 | 40 |
com.nyan.elesys.Coordinator | 7 | 14 |
com.nyan.elesys.Elevator | 3 | 9 |
com.nyan.elesys.Level | 1.62 | 13 |
com.nyan.elesys.MapKey | 1.25 | 5 |
com.nyan.elesys.Person | 1.2 | 6 |
com.nyan.elesys.PsgsList | 1.8 | 9 |
com.nyan.elesys.Request | 1 | 3 |
Package Complexity
Package | v(G)avg | v(G)tot |
---|---|---|
com.nyan | 1 | 1 |
com.nyan.elesys | 2.67 | 112 |
Module Complexity
Module | v(G)avg | v(G)tot |
---|---|---|
P7Project | 2.63 | 113 |
Project Complexity
Project | v(G)avg | v(G)tot |
---|---|---|
project | 2.63 | 113 |