1
2
3
4
5
6
7 package ca.uhn.cache.impl;
8
9 import java.util.Arrays;
10 import java.util.Date;
11
12 import ca.uhn.cache.IDimension;
13 import ca.uhn.cache.IPointQueryParam;
14 import ca.uhn.cache.IQueryParam;
15
16 /***
17 * A <code>IPointQueryParam</code> that selects data items with values along
18 * a certain dimension exactly equal to a certain <code>Date</code> value.
19 *
20 * @author <a href="mailto:bryan.tripp@uhn.on.ca">Bryan Tripp</a>
21 * @author <a href="mailto:alexei.guevara@uhn.on.ca">Alexei Guevara</a>
22 * @version $Revision: 1.1 $ updated on $Date: 2005/01/24 22:52:33 $ by $Author: bryan_tripp $
23 */
24 public class DateParam extends AbstractQueryParam implements IPointQueryParam {
25
26 private final Date myValue;
27
28 /***
29 * Creates a new <code>DateParam</code>.
30 *
31 * @param theDimension The dimension where this parameter is difined.
32 * @param theValue The value of this parameter.
33 */
34 public DateParam( IDimension theDimension, Date theValue ) {
35 super( theDimension );
36
37 assert theValue != null;
38
39 myValue = theValue;
40 }
41
42 /***
43 * {@inheritDoc}
44 */
45 public boolean intersects(IQueryParam theParam) {
46 boolean retVal = false;
47
48 if (super.intersects(theParam)) {
49 DateParam saturation = new DateParam(this.getDimension(), new Date(1));
50 if (getDistance(theParam, saturation) == 0) {
51 retVal = true;
52 }
53 }
54
55 return retVal;
56 }
57
58 /***
59 * @return Returns the value.
60 */
61 public Date getValue() {
62 return myValue;
63 }
64
65 /***
66 * @see ca.uhn.cache.IQueryParam#getDistance(ca.uhn.cache.IQueryParam, ca.uhn.cache.IQueryParam)
67 */
68 public float getDistance(IQueryParam theParam, IQueryParam theSaturationPoint) {
69 checkCompatibility(theParam, this.getDimension());
70 checkCompatibility(theSaturationPoint, this.getDimension());
71
72 if ( !(theSaturationPoint instanceof DateParam) ) {
73 throw new IllegalArgumentException("Saturation point should be a DateParam");
74 }
75
76 long here = this.getValue().getTime();
77 long there = 0;
78 if (theParam instanceof DateParam) {
79 there = ((DateParam) theParam).getValue().getTime();
80 } else if (theParam instanceof DateRangeParam) {
81 DateRangeParam range = (DateRangeParam) theParam;
82 if (range.getStart().getTime() <= here && range.getEnd().getTime() >= here) {
83 return 0;
84 } else if (range.getStart().getTime() > here) {
85 there = range.getStart().getTime();
86 } else {
87 there = range.getEnd().getTime();
88 }
89 }
90
91 long difference = Math.abs(here - there);
92 long saturation = ((DateParam) theSaturationPoint).getValue().getTime();
93
94 return getDistance(difference, saturation);
95 }
96
97 /***
98 * @param theDifference a difference (ms) between two times
99 * @param theSaturation the difference that defines the distance 1
100 * @return a monotonically increasing function of the difference, which
101 * is near-linear below the saturation, and approaches 1 for higher values
102 */
103 protected static float getDistance(long theDifference, long theSaturation) {
104 return (float) (1 - Math.exp(-(float)theDifference / theSaturation));
105 }
106
107 /***
108 * @see ca.uhn.cache.IQueryParam#merge(ca.uhn.cache.IQueryParam)
109 */
110 public IQueryParam merge(IQueryParam theParam) {
111 checkCompatibility(theParam, this.getDimension());
112
113 Date[] edges = null;
114 if (theParam instanceof DateParam) {
115 DateParam that = (DateParam) theParam;
116 edges = new Date[] {this.getValue(), that.getValue()};
117 } else if (theParam instanceof DateRangeParam) {
118 DateRangeParam that = (DateRangeParam) theParam;
119 edges = new Date[] {this.getValue(), that.getStart(), that.getEnd()};
120 }
121
122 Arrays.sort(edges);
123 return new DateRangeParam(this.getDimension(), edges[0], edges[edges.length-1]);
124 }
125
126 /***
127 * @param theParam another IQueryParam with which to check compatibility for merge()
128 * and distance()
129 * @param theDimension the dimension the param is expected to belong to
130 * @throws IllegalArgumentException if the given param is not of the given dimension
131 * or is not either a DateParam or DateRangeParam
132 */
133 protected static void checkCompatibility(IQueryParam theParam, IDimension theDimension) {
134 if (theParam == null) {
135 throw new IllegalArgumentException("IQueryParam can not be null");
136 }
137
138 if ( !(theParam instanceof DateParam) && !(theParam instanceof DateRangeParam) ) {
139 throw new IllegalArgumentException("Incompatible with "
140 + theParam.getClass().getName());
141 }
142
143 if ( !theDimension.equals(theParam.getDimension()) ) {
144 throw new IllegalArgumentException("Dimensions don't match: " + theDimension.getName()
145 + " vs " + theParam.getDimension().getName());
146 }
147 }
148 }