]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_4_2-src/main/classes/core/src/com/ibm/icu/impl/CalendarCache.java
go
[Dictionary.git] / jars / icu4j-4_4_2-src / main / classes / core / src / com / ibm / icu / impl / CalendarCache.java
1 /*\r
2  *******************************************************************************\r
3  * Copyright (C) 1996-2004, International Business Machines Corporation and    *\r
4  * others. All Rights Reserved.                                                *\r
5  *******************************************************************************\r
6  */\r
7 package com.ibm.icu.impl;\r
8 \r
9 /**\r
10  * @internal\r
11  */\r
12 public class CalendarCache\r
13 {\r
14     /**\r
15      * @internal\r
16      */\r
17     public CalendarCache() {\r
18         makeArrays(arraySize);\r
19     }\r
20     \r
21     private void makeArrays(int newSize) {\r
22         keys    = new long[newSize];\r
23         values  = new long[newSize];\r
24         \r
25         for (int i = 0; i < newSize; i++) {\r
26             values[i] = EMPTY;\r
27         }\r
28         arraySize = newSize;\r
29         threshold = (int)(arraySize * 0.75);\r
30         size = 0;\r
31     }\r
32     \r
33     /**\r
34      * @internal\r
35      */\r
36     public synchronized long get(long key) {\r
37         return values[findIndex(key)];\r
38     }\r
39     \r
40     /**\r
41      * @internal\r
42      */\r
43     public synchronized void put(long key, long value)\r
44     {\r
45         if (size >= threshold) {\r
46             rehash();\r
47         }\r
48         int index = findIndex(key);\r
49         \r
50         keys[index] = key;\r
51         values[index] = value;\r
52         size++;\r
53     }\r
54     \r
55     private final int findIndex(long key) {\r
56         int index = hash(key);\r
57         int delta = 0;\r
58         \r
59         while (values[index] != EMPTY && keys[index] != key)\r
60         {\r
61             if (delta == 0) {\r
62                 delta = hash2(key);\r
63             }\r
64             index = (index + delta) % arraySize;\r
65         }\r
66         return index;\r
67     }\r
68     \r
69     private void rehash()\r
70     {\r
71         int oldSize = arraySize;\r
72         long[] oldKeys = keys;\r
73         long[] oldValues = values;\r
74         \r
75         if (pIndex < primes.length - 1) {\r
76             arraySize = primes[++pIndex];\r
77         } else {\r
78             arraySize = arraySize * 2 + 1;\r
79         }\r
80         size = 0;\r
81         \r
82         makeArrays(arraySize);\r
83         for (int i = 0; i < oldSize; i++) {\r
84             if (oldValues[i] != EMPTY) {\r
85                 put(oldKeys[i], oldValues[i]);\r
86             }\r
87         }\r
88         oldKeys = oldValues = null; // Help out the garbage collector\r
89     }\r
90     \r
91     \r
92     /**\r
93      * Produce a uniformly-distributed hash value from an integer key.\r
94      * This is essentially a linear congruential random number generator\r
95      * that uses the key as its seed value.\r
96      */\r
97     private final int hash(long key)\r
98     {\r
99         int h = (int)((key * 15821 + 1) % arraySize);\r
100         if (h < 0) {\r
101             h += arraySize;\r
102         }\r
103         return h;\r
104     }\r
105     \r
106     private final int hash2(long key) {\r
107         return arraySize - 2 - (int)(key % (arraySize-2) );\r
108     }\r
109     \r
110     static private final int primes[] = {  // 5, 17, 31, 47, // for testing\r
111         61, 127, 509, 1021, 2039, 4093, 8191, 16381, 32749, 65521,\r
112         131071, 262139, \r
113     };\r
114 \r
115     private int     pIndex      = 0;\r
116     private int     size        = 0;\r
117     private int     arraySize   = primes[pIndex];\r
118     private int     threshold   = (arraySize * 3) / 4;\r
119     \r
120     private long[]  keys        = new long[arraySize];\r
121     private long[]  values      = new long[arraySize];\r
122 \r
123     /**\r
124      * @internal\r
125      */\r
126     static public  long EMPTY   = Long.MIN_VALUE;\r
127 }\r