EMMA Coverage Report (generated Thu Jan 20 11:39:44 EST 2011)
[all classes][com.hammurapi.extract]

COVERAGE SUMMARY FOR SOURCE FILE [ExtractorBase.java]

nameclass, %method, %block, %line, %
ExtractorBase.java100% (1/1)100% (7/7)78%  (335/431)83%  (49.2/59)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class ExtractorBase100% (1/1)100% (7/7)78%  (335/431)83%  (49.2/59)
compareTo (Extractor): ComparisonResult 100% (1/1)59%  (47/79)76%  (13/17)
extract (Object, Map, Object []): Object 100% (1/1)74%  (127/172)83%  (17.4/21)
ExtractorBase (double, TimeUnit): void 100% (1/1)81%  (29/36)78%  (7/9)
$SWITCH_TABLE$com$hammurapi$extract$ComparisonResult$Type (): int [] 100% (1/1)88%  (85/97)87%  (0.9/1)
createCacheEntry (): Map 100% (1/1)100% (4/4)100% (1/1)
equals (Object): boolean 100% (1/1)100% (25/25)100% (7/7)
getCost (): double 100% (1/1)100% (18/18)100% (3/3)

1package com.hammurapi.extract;
2 
3import java.util.HashMap;
4import java.util.Map;
5import java.util.concurrent.TimeUnit;
6 
7import com.hammurapi.extract.ComparisonResult.Type;
8 
9 
10/**
11 * Base class for extractors, implements value caching.
12 * @author Pavel Vlasov.
13 *
14 * @param <T>
15 * @param <V>
16 */
17public abstract class ExtractorBase<T, V, C> implements Extractor<T, V, C> {
18        
19        protected TimeUnit costUnit;
20        protected long invocations;
21        protected double totalCost;
22        protected boolean nanos;
23        protected double cost;
24        protected double initialCost;
25 
26        /**
27         * @param initialCost Initial cost. If positive, this value is added to the calculated cost. If costUnit is null,
28         * then cost is always equal to the initial cost. If negative and time unit is not null, then absolute value is used as first measurement of cost.
29         * @param costUnit If this argument is not null, then extractor cost is 
30         * calculated as average time to execute extractInternal() method in specified time unit.
31         * If time unit is nanoseconds or microseconds, then System.nanoTime() method is used for 
32         * measurement, otherwise Systsm.currentTimeMillis() is used.
33         */
34        protected ExtractorBase(double initialCost, TimeUnit costUnit) {                
35                this.costUnit = costUnit;
36                this.initialCost = initialCost;
37                if (initialCost<0 && costUnit!=null) {
38                        invocations = 1;
39                        totalCost = initialCost;
40                } else {
41                        this.cost = initialCost;                        
42                }
43                nanos = costUnit!=null && TimeUnit.MILLISECONDS.compareTo(costUnit)>0;
44        }
45        
46        @SuppressWarnings("unchecked")
47        public V extract(C context, Map<C, Map<Extractor<T, ? super V, C>, ? super V>> cache, T... obj) {
48                long start = 0;
49                if (costUnit!=null) {
50                        start = nanos ? System.nanoTime() : System.currentTimeMillis();
51                }
52                try {
53                        if (cache==null) {
54                                return extractInternal(context, cache, obj);
55                        }
56                        
57                        synchronized (cache) {
58                                Map<Extractor<T, ? super V, C>, ? super V> ce = cache.get(context);
59                                if (ce==null) {
60                                        ce = createCacheEntry();
61                                        cache.put(context, ce);
62                                }
63                                
64                                V ret = (V) ce.get(this);
65                                if (ret==null) {
66                                        ret = extractInternal(context, cache, obj);
67                                        ce.put(this, ret);
68                                }
69                                return ret;
70                        }
71                } finally {
72                        if (costUnit!=null) {
73                                long end = nanos ? System.nanoTime() : System.currentTimeMillis();
74                                totalCost += costUnit.convert(end-start, nanos ? TimeUnit.NANOSECONDS : TimeUnit.MICROSECONDS);
75                                ++invocations;
76                        }
77                }
78        }
79        
80        @Override
81        public double getCost() {
82                
83                if (invocations==0) {
84                        return cost;
85                }
86                
87                return cost + totalCost/invocations;
88        }
89 
90        /**
91         * Basic comparisons with True and False.
92         * @param otherPredicate
93         * @return
94         */
95        public ComparisonResult compareTo(Extractor<T, V, C> other) {
96                if (this==other) {
97                        return ComparisonResult.EQUAL_NM;
98                }
99                
100                // True is less restrictive than anything but self.
101                if (other instanceof True) {
102                        return ComparisonResult.MORE_RESTRICTIVE_NM;
103                }
104                
105                // False is more restrictive than anything but self.
106                if (other instanceof False) {
107                        return ComparisonResult.LESS_RESTRICTIVE_NM;
108                }
109                
110                if (other instanceof FacadeExtractor && !(this instanceof FacadeExtractor)) {
111                        ComparisonResult cr = other.compareTo(this);
112                        if (cr==null) {
113                                return cr;
114                        }
115                        switch (cr.getType()) {
116                        case EQUAL:
117                        case NOT_EQUAL:
118                        case OPPOSITE:
119                                return cr;
120                        case LESS_RESTRICTIVE:
121                                return new ComparisonResult(Type.MORE_RESTRICTIVE, ComparisonResult.inverse(cr.getIndexMap(), parameterIndices()));
122                        case MORE_RESTRICTIVE:
123                                return new ComparisonResult(Type.LESS_RESTRICTIVE, ComparisonResult.inverse(cr.getIndexMap(), parameterIndices()));
124                        case OPPOSITE_LESS_RESTRICTIVE:
125                                return new ComparisonResult(Type.OPPOSITE_LESS_RESTRICTIVE, ComparisonResult.inverse(cr.getIndexMap(), parameterIndices()));
126                        case OPPOSITE_MORE_RESTRICTIVE:
127                                return new ComparisonResult(Type.OPPOSITE_MORE_RESTRICTIVE, ComparisonResult.inverse(cr.getIndexMap(), parameterIndices()));
128                        }
129                }
130                
131                return ComparisonResult.NOT_EQUAL_NM;
132        }
133        
134 
135        protected abstract V extractInternal(C context, Map<C, Map<Extractor<T, ? super V, C>, ? super V>> cache, T... obj);
136        
137        protected Map<Extractor<T, ? super V, C>, ? super V> createCacheEntry() {
138                return new HashMap<Extractor<T,? super V,C>, V>();
139        }
140        
141        @Override
142        public boolean equals(Object obj) {
143                if (this == obj) {
144                        return true;
145                }
146                if (obj instanceof Extractor) {
147                        ComparisonResult cr = compareTo((Extractor) obj);
148                        if (ComparisonResult.Type.EQUAL.equals(cr.getType()) && cr.isOneToOneMapping()) {
149                                return true;
150                        }
151                }
152                return false;
153        }
154        
155}

[all classes][com.hammurapi.extract]
EMMA 2.0.5312 EclEmma Fix 2 (C) Vladimir Roubtsov