(K key, int hash, V value, boolean onlyIfAbsent)
| 2858 | } |
| 2859 | |
| 2860 | @Nullable |
| 2861 | V put(K key, int hash, V value, boolean onlyIfAbsent) { |
| 2862 | lock(); |
| 2863 | try { |
| 2864 | long now = map.ticker.read(); |
| 2865 | preWriteCleanup(now); |
| 2866 | |
| 2867 | int newCount = this.count + 1; |
| 2868 | if (newCount > this.threshold) { // ensure capacity |
| 2869 | expand(); |
| 2870 | newCount = this.count + 1; |
| 2871 | } |
| 2872 | |
| 2873 | AtomicReferenceArray<ReferenceEntry<K, V>> table = this.table; |
| 2874 | int index = hash & (table.length() - 1); |
| 2875 | ReferenceEntry<K, V> first = table.get(index); |
| 2876 | |
| 2877 | // Look for an existing entry. |
| 2878 | for (ReferenceEntry<K, V> e = first; e != null; e = e.getNext()) { |
| 2879 | K entryKey = e.getKey(); |
| 2880 | if (e.getHash() == hash |
| 2881 | && entryKey != null |
| 2882 | && map.keyEquivalence.equivalent(key, entryKey)) { |
| 2883 | // We found an existing entry. |
| 2884 | |
| 2885 | ValueReference<K, V> valueReference = e.getValueReference(); |
| 2886 | V entryValue = valueReference.get(); |
| 2887 | |
| 2888 | if (entryValue == null) { |
| 2889 | ++modCount; |
| 2890 | if (valueReference.isActive()) { |
| 2891 | enqueueNotification( |
| 2892 | key, hash, entryValue, valueReference.getWeight(), RemovalCause.COLLECTED); |
| 2893 | setValue(e, key, value, now); |
| 2894 | newCount = this.count; // count remains unchanged |
| 2895 | } else { |
| 2896 | setValue(e, key, value, now); |
| 2897 | newCount = this.count + 1; |
| 2898 | } |
| 2899 | this.count = newCount; // write-volatile |
| 2900 | evictEntries(e); |
| 2901 | return null; |
| 2902 | } else if (onlyIfAbsent) { |
| 2903 | // Mimic |
| 2904 | // "if (!map.containsKey(key)) ... |
| 2905 | // else return map.get(key); |
| 2906 | recordLockedRead(e, now); |
| 2907 | return entryValue; |
| 2908 | } else { |
| 2909 | // clobber existing entry, count remains unchanged |
| 2910 | ++modCount; |
| 2911 | enqueueNotification( |
| 2912 | key, hash, entryValue, valueReference.getWeight(), RemovalCause.REPLACED); |
| 2913 | setValue(e, key, value, now); |
| 2914 | evictEntries(e); |
| 2915 | return entryValue; |
| 2916 | } |
| 2917 | } |
nothing calls this directly
no test coverage detected