CSG 260 Fall 2003 Advanced Software Development Homework 3 ========== Due date: Oct. 9 PART 1: Caching: An Optimization Aspect Consider the program in directory $ASD/hw/3/container which implements a container checking problem in a recursive style. (An iterative version: http://www.ccs.neu.edu/home/lieber/courses/csu670/f03/hw/3/onlyDJ-capacity-with-stack/ ) In the recursive solution the traversal methods return a value and the traversal results of the subtraversal are combined at each node. PART 1a: You implement a caching aspect as follows: Cache the value of the sum for each container and the number of violations. If the same container is checked again and there has been no change, we can reuse the cached values. Modify the weights of some of the Item-objects during the same run of the program and invalidate the appropriate cached values. Recheck the container and make sure that the result is still correct. Can the caching aspect (an optimization aspect) be written so that no change is needed to the base program? The answer is positive. PART 1b: Is the given program in $ASD/container free of caching issues? Not completely! To invalidate the cached values you need the capability to go up the containment hierarchy. Clarifcation: you need to go up the hierarchy because if a subcontainer increases in weight, a distant super container may go over capacity even though the ones in between are not over capacity. If you don't cache, you don't need those back pointers which give the ability to go up the hierarchy (back = parent). Rewrite $ASD/container with a back pointer aspect and use it together with your caching aspect. This will make your base program cleaner and the back pointer aspect can also be used for other purposes than caching. PART 1c: Explore the design space for the caching aspect. It is possible to use either a Hashtable or to store the cached value directly on the Container-objects. Implement both versions in AspectJ. PART 1d: >From all the above programs that you have developed choose the one that you consider as the best solution and focus on using abstract aspects that are reusable in other contexts. Discuss the reusability of your abstract aspects. PART 2: Graph connections: In AspectJ and Demeter we work with static/dynamic call graphs and class/object graphs. How are the static/dynamic call graphs and class/object graphs related during an execution of a program? Discuss the various connections between these graphs. PART 3: Planning to extend AspectJ PART 3a: Translate the following to AspectJ and test the aspect with a concrete Java program having classes A,R,S,B and at least one extra class between A and R, and between S and B. aspect SimulateTraversal { int count = 0; // inter-type declarations of traversal methods // traversal t = from a1:A through ->R,x,S to b1:B UNKNOWN1 // pointcuts // visiting node A pointcut visiting_A(A a1) : call(UNKNOWN2) // should be traversal(t) && target(a1); // visiting node B pointcut visiting_B(B b1) : call(UNKNOWN3) && target(b1); // crossing edge named x from R to S pointcut crossing_x(R r1, S s1) : call(UNKOWN4) // should be crossing(x) && this(r1) && target(s1); // transporting A-object down to B-object pointcut AandB(A a1, B b1): cflow(visiting_A(a1)) && visiting_B(b1); // advice before (A a1) : visiting_A(a1) {print(a1);} before (A a1, B b1) : AandB(a1, b1) {print(b1); print(a1); count++;} after (A a1) : visiting_A(a1) {print(count);} } PART 3b: Implement the aspect SimulateTraversal without cflow. PART 3c: Consider the DJ tool, http://www.ccs.neu.edu/research/demeter/software/docs/api/ edu.neu.ccs.demeter.dj.Visitor DJ expresses sets of join points in traversals. Express the following patterns: *,x,*: select all edges with label x. Source,*,Target: select all edges from Source to Target. Source,x,*: select all edges from Source through edge x. in DJ.