|
|||||||||||||||||||
Source file | Conditionals | Statements | Methods | TOTAL | |||||||||||||||
FactHandleList.java | 88.9% | 94.3% | 100% | 93.5% |
|
1 | package org.drools.reteoo; | |
2 | ||
3 | /* | |
4 | * $Id: FactHandleList.java,v 1.6 2005/02/02 00:23:21 mproctor Exp $ | |
5 | * | |
6 | * Copyright 2001-2004 (C) The Werken Company. All Rights Reserved. | |
7 | * | |
8 | * Redistribution and use of this software and associated documentation | |
9 | * ("Software"), with or without modification, are permitted provided that the | |
10 | * following conditions are met: | |
11 | * | |
12 | * 1. Redistributions of source code must retain copyright statements and | |
13 | * notices. Redistributions must also contain a copy of this document. | |
14 | * | |
15 | * 2. Redistributions in binary form must reproduce the above copyright notice, | |
16 | * this list of conditions and the following disclaimer in the documentation | |
17 | * and/or other materials provided with the distribution. | |
18 | * | |
19 | * 3. The name "drools" must not be used to endorse or promote products derived | |
20 | * from this Software without prior written permission of The Werken Company. | |
21 | * For written permission, please contact bob@werken.com. | |
22 | * | |
23 | * 4. Products derived from this Software may not be called "drools" nor may | |
24 | * "drools" appear in their names without prior written permission of The Werken | |
25 | * Company. "drools" is a trademark of The Werken Company. | |
26 | * | |
27 | * 5. Due credit should be given to The Werken Company. (http://werken.com/) | |
28 | * | |
29 | * THIS SOFTWARE IS PROVIDED BY THE WERKEN COMPANY AND CONTRIBUTORS ``AS IS'' | |
30 | * AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
31 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
32 | * ARE DISCLAIMED. IN NO EVENT SHALL THE WERKEN COMPANY OR ITS CONTRIBUTORS BE | |
33 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
34 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
35 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
36 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
37 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
38 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
39 | * POSSIBILITY OF SUCH DAMAGE. | |
40 | * | |
41 | */ | |
42 | ||
43 | import java.io.Serializable; | |
44 | import java.util.Arrays; | |
45 | ||
46 | import org.drools.FactHandle; | |
47 | import org.drools.rule.Declaration; | |
48 | ||
49 | /** | |
50 | * Specialised array of {@link FactHandle}s intended to be keyed by a {@link Declaration}s | |
51 | * index. The list only ever contains as many elements as necessary to hold a handle at the | |
52 | * position specified by the largest Declaration index. As a result, the list will neccessarily | |
53 | * contain <code>NULL</code> values. | |
54 | * | |
55 | * This class exists purely for performance reasons and as such, many assumptions have been | |
56 | * made regarding behaviour based on know usage. Therefore, this class should in no way be | |
57 | * considered a general purpose data structure. Hence it resides in this package and not a more | |
58 | * generic "util" package. | |
59 | * | |
60 | * @author <a href="mailto:simon@redhillconsulting.com.au">Simon Harris</a> | |
61 | */ | |
62 | final class FactHandleList implements Serializable | |
63 | { | |
64 | /** Empty list for testing purposes only. */ | |
65 | static final FactHandleList EMPTY_LIST = new FactHandleList( ); | |
66 | ||
67 | /** The list of handles. */ | |
68 | private final FactHandle[] handles; | |
69 | ||
70 | /** The cached hash code value. */ | |
71 | private final int hashCode; | |
72 | ||
73 | /** | |
74 | * Private constructor for creating the {@link #EMPTY_LIST}. | |
75 | */ | |
76 | 15 | private FactHandleList() |
77 | { | |
78 | 15 | handles = new FactHandleImpl[ 0 ]; |
79 | 15 | hashCode = 0; |
80 | } | |
81 | ||
82 | /** | |
83 | * Join two lists. | |
84 | * @param left The left list. | |
85 | * @param right The right list. | |
86 | */ | |
87 | 24802 | public FactHandleList( FactHandleList left, |
88 | FactHandleList right ) | |
89 | { | |
90 | 24802 | this.handles = new FactHandle[ Math.max( left.handles.length, right.handles.length ) ]; |
91 | ||
92 | 24802 | System.arraycopy( left.handles, 0, this.handles, 0, left.handles.length ); |
93 | ||
94 | 24802 | int hashCode = left.hashCode; |
95 | 24802 | FactHandle handle; |
96 | ||
97 | 24802 | for ( int i = right.handles.length - 1; i >= 0; i-- ) |
98 | { | |
99 | 50855 | handle = right.handles[ i ]; |
100 | 50855 | if ( handle != null && this.handles[ i ] == null ) |
101 | { | |
102 | 46819 | this.handles[ i ] = handle; |
103 | 46819 | hashCode += handle.hashCode( ); |
104 | } | |
105 | } | |
106 | ||
107 | 24802 | this.hashCode = hashCode; |
108 | } | |
109 | ||
110 | /** | |
111 | * Single value constructor. | |
112 | * @param index The index at which the handle will be placed. | |
113 | * @param handle The handle to use. | |
114 | */ | |
115 | 1927 | public FactHandleList( int index, FactHandle handle ) |
116 | { | |
117 | 1927 | this.handles = new FactHandleImpl[ index + 1 ]; |
118 | 1927 | this.handles[ index ] = handle; |
119 | 1927 | this.hashCode = handle.hashCode( ); |
120 | } | |
121 | ||
122 | /** | |
123 | * Obtains the handle at a specified index. | |
124 | * @param index The position from which the handle should be obtained. | |
125 | * @return The handle; or <code>null</code> if no handle exists. | |
126 | * @throws ArrayIndexOutOfBoundsException if <code>index</code> > {@link #size()}. | |
127 | */ | |
128 | 100786 | public FactHandle get( int index ) |
129 | { | |
130 | 100786 | return this.handles[ index ]; |
131 | } | |
132 | ||
133 | /** | |
134 | * Determines if the list contains a specified handle. | |
135 | * @param handle The handle to search for. | |
136 | * @return <code>true</code> if the handle is found; otherwise <code>false</code> | |
137 | */ | |
138 | 8 | public boolean contains( FactHandle handle ) |
139 | { | |
140 | 8 | for ( int i = handles.length - 1; i >= 0; i-- ) |
141 | { | |
142 | 16 | if ( handle.equals( handles[ i ] ) ) |
143 | { | |
144 | 4 | return true; |
145 | } | |
146 | } | |
147 | ||
148 | 4 | return false; |
149 | } | |
150 | ||
151 | /** | |
152 | * Determines if the list is a super-set of another list. | |
153 | * @param other The list to be checked. | |
154 | * @return <code>true</code> if this list contains all values | |
155 | * from the other list; <code>false</code> otherwise. | |
156 | */ | |
157 | 53395 | public boolean containsAll( FactHandleList other ) |
158 | { | |
159 | 53395 | if ( other.handles.length > this.handles.length ) |
160 | { | |
161 | 22807 | return false; |
162 | } | |
163 | ||
164 | 30588 | FactHandle handle; |
165 | 30588 | for ( int i = other.handles.length - 1; i >= 0; i-- ) |
166 | { | |
167 | 43261 | handle = other.handles[ i ]; |
168 | 43261 | if ( handle != null && !handle.equals( this.handles[ i ] ) ) |
169 | { | |
170 | 23577 | return false; |
171 | } | |
172 | } | |
173 | 7011 | return true; |
174 | } | |
175 | ||
176 | /** | |
177 | * Obtains the length of the list. | |
178 | * @return The length of the list, including all <code>null</code> values. | |
179 | */ | |
180 | 5870 | public int size() |
181 | { | |
182 | 5870 | return this.handles.length; |
183 | } | |
184 | ||
185 | 28507 | public int hashCode() |
186 | { | |
187 | 28507 | return this.hashCode; |
188 | } | |
189 | ||
190 | 10 | public boolean equals( Object object ) |
191 | { | |
192 | 10 | if ( this == object ) |
193 | { | |
194 | 0 | return true; |
195 | } | |
196 | ||
197 | 10 | if ( object == null || getClass( ) != object.getClass( ) ) |
198 | { | |
199 | 0 | return false; |
200 | } | |
201 | ||
202 | 10 | return Arrays.equals( this.handles, ( ( FactHandleList ) object ).handles ); |
203 | } | |
204 | } |
|