为了保障原创作者在本站发表文章的利益, 并维护本站原创的精神, 特声明: RIAShanghai对有以下任何情况之一的文章将不通知作者并直接进行快意删除:
- 非原创, 或者原创但一文多发;
- 各种形式的广告与吹擂;
- 不符合本站文章格式.
欢迎各位读者监督. 谢谢合作. 另: 作为Adobe正式的UG, 我们将把Adobe不定期分发的软件,书籍及各种纪念品赠送给发文活跃的作者, 共同进步.
OSGi defines a very good module management system. The modules mainly communicate with the framework instead of messing around one another. However, there are cases that a module depends on other modules. Consider the modules in the diagram below (the arrow points to the depending module). Module C depends on A and D; module A, D and W depend on B. In order to run C, we need to run all of its depending modules first, for instance, one possible execution order is B, A, D, C. How to determine the order? It's easy. The answer is Topological sort.
The idea of topological sort is simple yet powerful. You use DFS to traverse the whole graph, i.e., all the vertices. The topological order is the same as the visiting finish order of vertices.
My implementation of finding all the depending modules for a given module (module_) and putting everything in topo sorted order:
// Topological sort.
// 0. Clear visit status
clearGraphVisit();
// 1. direct DFS - discover connected nodes and perform DFS at the same time.
var sortedOrder:Array = new Array(); // to order nodes.
dfsVisit(module_, sortedOrder);
Required functions:
/**
* Sets the visit mode of all modules to NO_VISIT.
*/
private function clearGraphVisit():void {
for each(var m:Module in _idToModuleMapping) {
m.visitStatus = Module.NO_VISIT;
}
}
/**
* Visits the given module in DFS and inserts finished node to the order array.
* @param module_ the node to be visited, which should be in Module.NO_VISIT mode.
* @param graph the collection of all the vertices in the graph
* @param sortedOrder the
*/
private function dfsVisit(module_:Module, sortedOrder:Array):void {
if(module_.visitStatus != Module.NO_VISIT) {
throw new Error("Invalid visit status - must be in NO_VISIT");
}
module_.visitStatus = Module.VISIT_BEGIN;
for(var i:int = 0; module_.dependingModules != null && i < module_.dependingModules.length; i++) {
var m:Module = module_.dependingModules.getItemAt(i) as Module;
if(m.visitStatus == Module.NO_VISIT) {
dfsVisit(m, sortedOrder);
}else if(m.visitStatus == Module.VISIT_BEGIN) {
throw new Error("Cyclic DAG! ");
}else if(m.visitStatus == Module.VISIT_END) {
// skip.
}else{
throw new Error("Invalid visit status: " + m.visitStatus);
}
}
module_.visitStatus = Module.VISIT_END;
sortedOrder.push(module_);
}
In less than twenty lines, you can get the topo order, know whether the graph is cyclic (e.g., C -> A -> C). That's why DFS is one of my favorite algorithms :)
回應
cool 期待你的AAF
cool 期待你的AAF
lw0110's Blog: http://chestnutjoelee.spaces.live.com/