(K key, int hash, V value, boolean onlyIfAbsent)
| 2915 | } |
| 2916 | |
| 2917 | @Nullable |
| 2918 | V put(K key, int hash, V value, boolean onlyIfAbsent) { |
| 2919 | lock(); |
| 2920 | try { |
| 2921 | long now = map.ticker.read(); |
| 2922 | preWriteCleanup(now); |
| 2923 | int newCount = this.count + 1; |
| 2924 | if (newCount > this.threshold) { // ensure capacity |
| 2925 | expand(); |
| 2926 | newCount = this.count + 1; |
| 2927 | } |
| 2928 | AtomicReferenceArray<ReferenceEntry<K, V>> table = this.table; |
| 2929 | int index = hash & (table.length() - 1); |
| 2930 | ReferenceEntry<K, V> first = table.get(index); |
| 2931 | |
| 2932 | // Look for an existing entry. |
| 2933 | for (ReferenceEntry<K, V> e = first; e != null; e = e.getNext()) { |
| 2934 | K entryKey = e.getKey(); |
| 2935 | if (e.getHash() == hash && entryKey != null |
| 2936 | && map.keyEquivalence.equivalent(key, entryKey)) { |
| 2937 | // We found an existing entry. |
| 2938 | ValueReference<K, V> valueReference = e.getValueReference(); |
| 2939 | V entryValue = valueReference.get(); |
| 2940 | if (entryValue == null) { |
| 2941 | ++modCount; |
| 2942 | if (valueReference.isActive()) { |
| 2943 | enqueueNotification(key, hash, entryValue, valueReference.getWeight(), RemovalCause.COLLECTED); |
| 2944 | setValue(e, key, value, now); |
| 2945 | newCount = this.count; // count remains unchanged |
| 2946 | } else { |
| 2947 | setValue(e, key, value, now); |
| 2948 | newCount = this.count + 1; |
| 2949 | } |
| 2950 | this.count = newCount; // write-volatile |
| 2951 | evictEntries(e); |
| 2952 | return null; |
| 2953 | } |
| 2954 | else if (onlyIfAbsent) { |
| 2955 | // Mimic |
| 2956 | // "if (!map.containsKey(key)) ... |
| 2957 | // else return map.get(key); |
| 2958 | recordLockedRead(e, now); |
| 2959 | return entryValue; |
| 2960 | } else { |
| 2961 | // clobber existing entry, count remains unchanged |
| 2962 | ++modCount; |
| 2963 | enqueueNotification(key, hash, entryValue, valueReference.getWeight(), RemovalCause.REPLACED); |
| 2964 | setValue(e, key, value, now); |
| 2965 | evictEntries(e); |
| 2966 | return entryValue; |
| 2967 | } |
| 2968 | } |
| 2969 | } |
| 2970 | |
| 2971 | // Create a new entry. |
| 2972 | |
| 2973 | ++modCount; |
| 2974 | ReferenceEntry<K, V> newEntry = newEntry(key, hash, first); |
nothing calls this directly
no test coverage detected