1 /* 2 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.xml.internal.rngom.binary; 27 28 final class PatternInterner { 29 private static final int INIT_SIZE = 256; 30 private static final float LOAD_FACTOR = 0.3f; 31 private Pattern[] table; 32 private int used; 33 private int usedLimit; 34 35 PatternInterner() { 36 table = null; 37 used = 0; 38 usedLimit = 0; 39 } 40 41 PatternInterner(PatternInterner parent) { 42 table = parent.table; 43 if (table != null) 44 table = (Pattern[]) table.clone(); 45 used = parent.used; 46 usedLimit = parent.usedLimit; 47 } 48 49 Pattern intern(Pattern p) { 50 int h; 51 52 if (table == null) { 53 table = new Pattern[INIT_SIZE]; 54 usedLimit = (int) (INIT_SIZE * LOAD_FACTOR); 55 h = firstIndex(p); 56 } else { 57 for (h = firstIndex(p); table[h] != null; h = nextIndex(h)) { 58 if (p.samePattern(table[h])) 59 return table[h]; 60 } 61 } 62 if (used >= usedLimit) { 63 // rehash 64 Pattern[] oldTable = table; 65 table = new Pattern[table.length << 1]; 66 for (int i = oldTable.length; i > 0;) { 67 --i; 68 if (oldTable[i] != null) { 69 int j; 70 for (j = firstIndex(oldTable[i]); 71 table[j] != null; 72 j = nextIndex(j)); 73 table[j] = oldTable[i]; 74 } 75 } 76 for (h = firstIndex(p); table[h] != null; h = nextIndex(h)); 77 usedLimit = (int) (table.length * LOAD_FACTOR); 78 } 79 used++; 80 table[h] = p; 81 return p; 82 } 83 84 private int firstIndex(Pattern p) { 85 return p.patternHashCode() & (table.length - 1); 86 } 87 88 private int nextIndex(int i) { 89 return i == 0 ? table.length - 1 : i - 1; 90 } 91 }