<s> package org . eclipse . jdt . internal . core . util ; import java . lang . ref . ReferenceQueue ; import java . lang . ref . WeakReference ; import org . eclipse . jdt . core . compiler . CharOperation ; public class WeakHashSetOfCharArray { public static class HashableWeakReference extends WeakReference { public int hashCode ; public HashableWeakReference ( char [ ] referent , ReferenceQueue queue ) { super ( referent , queue ) ; this . hashCode = CharOperation . hashCode ( referent ) ; } public boolean equals ( Object obj ) { if ( ! ( obj instanceof HashableWeakReference ) ) return false ; char [ ] referent = ( char [ ] ) get ( ) ; char [ ] other = ( char [ ] ) ( ( HashableWeakReference ) obj ) . get ( ) ; if ( referent == null ) return other == null ; return CharOperation . equals ( referent , other ) ; } public int hashCode ( ) { return this . hashCode ; } public String toString ( ) { char [ ] referent = ( char [ ] ) get ( ) ; if ( referent == null ) return "[hashCode=" + this . hashCode + "" ; return "[hashCode=" + this . hashCode + "] \"" + new String ( referent ) + '\"' ; } } HashableWeakReference [ ] values ; public int elementSize ; int threshold ; ReferenceQueue referenceQueue = new ReferenceQueue ( ) ; public WeakHashSetOfCharArray ( ) { this ( 5 ) ; } public WeakHashSetOfCharArray ( int size ) { this . elementSize = 0 ; this . threshold = size ; int extraRoom = ( int ) ( size * 1.75f ) ; if ( this . threshold == extraRoom ) extraRoom ++ ; this . values = new HashableWeakReference [ extraRoom ] ; } public char [ ] add ( char [ ] array ) { cleanupGarbageCollectedValues ( ) ; int valuesLength = this . values . length , index = ( CharOperation . hashCode ( array ) & 0x7FFFFFFF ) % valuesLength ; HashableWeakReference currentValue ; while ( ( currentValue = this . values [ index ] ) != null ) { char [ ] referent ; if ( CharOperation . equals ( array , referent = ( char [ ] ) currentValue . get ( ) ) ) { return referent ; } if ( ++ index == valuesLength ) { index = 0 ; } } this . values [ index ] = new HashableWeakReference ( array , this . referenceQueue ) ; if ( ++ this . elementSize > this . threshold ) rehash ( ) ; return array ; } private void addValue ( HashableWeakReference value ) { char [ ] array = ( char [ ] ) value . get ( ) ; if ( array == null ) return ; int valuesLength = this . values . length ; int index = ( value . hashCode & 0x7FFFFFFF ) % valuesLength ; HashableWeakReference currentValue ; while ( ( currentValue = this . values [ index ] ) != null ) { if ( CharOperation . equals ( array , ( char [ ] ) currentValue . get ( ) ) ) { return ; } if ( ++ index == valuesLength ) { index = 0 ; } } this . values [ index ] = value ; if ( ++ this . elementSize > this . threshold ) rehash ( ) ; } private void cleanupGarbageCollectedValues ( ) { HashableWeakReference toBeRemoved ; while ( ( toBeRemoved = ( HashableWeakReference ) this . referenceQueue . poll ( ) ) != null ) { int hashCode = toBeRemoved . hashCode ; int valuesLength = this . values . length ; int index = ( hashCode & 0x7FFFFFFF ) % valuesLength ; HashableWeakReference currentValue ; while ( ( currentValue = this . values [ index ] ) != null ) { if ( currentValue == toBeRemoved ) { int sameHash = index ; int current ; while ( ( currentValue = this . values [ current = ( sameHash + 1 ) % valuesLength ] ) != null && currentValue . hashCode == hashCode ) sameHash = current ; this . values [ index ] = this . values [ sameHash ] ; this . values [ sameHash ] = null ; this . elementSize -- ; break ; } if ( ++ index == valuesLength ) { index = 0 ; } } } } public boolean contains ( char [ ] array ) { return get ( array ) != null ; } public char [ ] get ( char [ ] array ) { cleanupGarbageCollectedValues ( ) ; int valuesLength = this . values . length ; int index = ( CharOperation . hashCode ( array ) & 0x7FFFFFFF ) % valuesLength ; HashableWeakReference currentValue ; while ( ( currentValue = this . values [ index ] ) != null ) { char [ ] referent ; if ( CharOperation . equals ( array , referent = ( char [ ] ) currentValue . get ( ) ) ) { return referent ; } if ( ++ index == valuesLength ) { index = 0 ; } } return null ; } private void rehash ( ) { WeakHashSetOfCharArray newHashSet = new WeakHashSetOfCharArray ( this . elementSize * 2 ) ; newHashSet . referenceQueue = this . referenceQueue ; HashableWeakReference currentValue ; for ( int i = 0 , length = this . values . length ; i < length ; i ++ ) if ( ( currentValue = this . values [ i ] ) != null ) newHashSet . addValue ( currentValue ) ; this . values = newHashSet . values ; this . threshold = newHashSet . threshold ; this . elementSize = newHashSet . elementSize ; } public char [ ] remove ( char [ ] array ) { cleanupGarbageCollectedValues ( ) ; int valuesLength = this . values . length ; int index = ( CharOperation . hashCode ( array ) & 0x7FFFFFFF ) % valuesLength ; HashableWeakReference currentValue ; while ( ( currentValue = this . values [ index ] ) != null ) { char [ ] referent ; if ( CharOperation . equals ( array , referent = ( char [ ] ) currentValue . get ( ) ) ) { this . elementSize -- ; this . values [ index ] = null ; rehash ( ) ; return referent ; } if ( ++ index == valuesLength ) { index = 0 ; } } return null ; } public int size ( ) { return this . elementSize ; } public String toString ( ) { StringBuffer buffer = new StringBuffer ( "{" ) ; for ( int i = 0 , length = this . values . length ; i < length ; i ++ ) { HashableWeakReference value = this . values [ i ] ; if ( value != null ) { char [ ] ref = ( char [ ] ) value . get ( ) ; if ( ref != null ) { buffer . append ( '\"' ) ; buffer . append ( ref ) ; buffer . append ( "\", " ) ; } } } buffer . append ( "}" ) ; return buffer . toString ( ) ; } } </s>