View Javadoc
1   /*
2    * Copyright 2004-2022 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *    https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package com.ibatis.sqlmap.engine.cache;
17  
18  import java.io.Serializable;
19  import java.util.ArrayList;
20  import java.util.List;
21  
22  /**
23   * Hash value generator for cache keys.
24   */
25  public class CacheKey implements Cloneable, Serializable {
26  
27    /** The Constant DEFAULT_MULTIPLYER. */
28    private static final int DEFAULT_MULTIPLYER = 37;
29  
30    /** The Constant DEFAULT_HASHCODE. */
31    private static final int DEFAULT_HASHCODE = 17;
32  
33    /** The multiplier. */
34    private int multiplier;
35  
36    /** The hashcode. */
37    private int hashcode;
38  
39    /** The checksum. */
40    private long checksum;
41  
42    /** The count. */
43    private int count;
44  
45    /** The param list. */
46    private List paramList = new ArrayList();
47  
48    /**
49     * Default constructor.
50     */
51    public CacheKey() {
52      hashcode = DEFAULT_HASHCODE;
53      multiplier = DEFAULT_MULTIPLYER;
54      count = 0;
55    }
56  
57    /**
58     * Constructor that supplies an initial hashcode.
59     *
60     * @param initialNonZeroOddNumber
61     *          - the hashcode to use
62     */
63    public CacheKey(int initialNonZeroOddNumber) {
64      hashcode = initialNonZeroOddNumber;
65      multiplier = DEFAULT_MULTIPLYER;
66      count = 0;
67    }
68  
69    /**
70     * Costructor that supplies an initial hashcode and multiplier.
71     *
72     * @param initialNonZeroOddNumber
73     *          - the hashcode to use
74     * @param multiplierNonZeroOddNumber
75     *          - the multiplier to use
76     */
77    public CacheKey(int initialNonZeroOddNumber, int multiplierNonZeroOddNumber) {
78      hashcode = initialNonZeroOddNumber;
79      multiplier = multiplierNonZeroOddNumber;
80      count = 0;
81    }
82  
83    /**
84     * Updates this object with new information based on an int value.
85     *
86     * @param x
87     *          - the int value
88     *
89     * @return the cache key
90     */
91    public CacheKey update(int x) {
92      update(Integer.valueOf(x));
93      return this;
94    }
95  
96    /**
97     * Updates this object with new information based on an object.
98     *
99     * @param object
100    *          - the object
101    *
102    * @return the cachekey
103    */
104   public CacheKey update(Object object) {
105     int baseHashCode = object.hashCode();
106 
107     count++;
108     checksum += baseHashCode;
109     baseHashCode *= count;
110 
111     hashcode = multiplier * hashcode + baseHashCode;
112 
113     paramList.add(object);
114 
115     return this;
116   }
117 
118   @Override
119   public boolean equals(Object object) {
120     if (this == object)
121       return true;
122     if (!(object instanceof CacheKey))
123       return false;
124 
125     final CacheKey cacheKey = (CacheKey) object;
126 
127     if (hashcode != cacheKey.hashcode)
128       return false;
129     if (checksum != cacheKey.checksum)
130       return false;
131     if (count != cacheKey.count)
132       return false;
133 
134     for (int i = 0; i < paramList.size(); i++) {
135       Object thisParam = paramList.get(i);
136       Object thatParam = cacheKey.paramList.get(i);
137       if (thisParam == null) {
138         if (thatParam != null)
139           return false;
140       } else {
141         if (!thisParam.equals(thatParam))
142           return false;
143       }
144     }
145 
146     return true;
147   }
148 
149   @Override
150   public int hashCode() {
151     return hashcode;
152   }
153 
154   @Override
155   public String toString() {
156     StringBuilder returnValue = new StringBuilder().append(hashcode).append('|').append(checksum);
157     for (int i = 0; i < paramList.size(); i++) {
158       returnValue.append('|').append(paramList.get(i));
159     }
160 
161     return returnValue.toString();
162   }
163 
164   @Override
165   public CacheKey clone() throws CloneNotSupportedException {
166     CacheKey clonedCacheKey = (CacheKey) super.clone();
167     clonedCacheKey.paramList = new ArrayList<Object>(paramList);
168     return clonedCacheKey;
169   }
170 
171 }