src/main/java/com/googlecode/objectify/cache/EntityMemcache.java
public void putAll(final Collection<Bucket> updates) {
		final Set<Key> good = this.cachePutIfUntouched(updates);

		if (good.size() == updates.size())
			return;

		// Figure out which ones were bad
		final List<Key> bad = updates.stream()
				.map(Bucket::getKey)
				.filter(key -> !good.contains(key))
				.collect(Collectors.toList());

		if (!bad.isEmpty()) {
			// So we had some collisions.  We need to reset these back to null, but do it in a safe way - if we
			// blindly set null something already null, it will break any putIfUntouched() which saw the first null.
			// This could result in write contention starving out a real write.  The solution is to only reset things
			// that are not already null.

			final Map<Key, Object> cached = this.cacheGetAll(bad);

			// Remove the stuff we don't care about
			cached.values().removeIf(Objects::isNull);

			this.empty(cached.keySet());
		}
	}
public void putAll(final Collection<Bucket> updates) {
		final Set<Key> good = this.cachePutIfUntouched(updates);

		if (good.size() == updates.size())
			return;

		// Figure out which ones were bad
		final List<Key> bad = updates.stream()
				.map(Bucket::getKey)
				.filter(key -> !good.contains(key))
				.collect(Collectors.toList());

		if (!bad.isEmpty()) {
			// So we had some collisions.  We need to reset these back to null, but do it in a safe way - if we
			// blindly set null something already null, it will break any putIfUntouched() which saw the first null.
			// This could result in write contention starving out a real write.  The solution is to only reset things
			// that are not already null.

			final Map<Key, Object> cached = this.cacheGetAll(bad);

			// Remove the stuff we don't care about
			cached.values().removeIf(Objects::isNull);

			this.empty(cached.keySet());
		}
	}
public void putAll ( final Collection < Bucket > updates ) { final Set < Key > good = this . cachePutIfUntouched ( updates ) ; if ( good . size ( ) == updates . size ( ) ) return ; // Figure out which ones were bad
 final List < Key > bad = updates . stream ( ) . map ( Bucket :: getKey ) . filter ( key -> ! good . contains ( key ) ) . collect ( Collectors . toList ( ) ) ; if ( ! bad . isEmpty ( ) ) { // So we had some collisions.  We need to reset these back to null, but do it in a safe way - if we
 // blindly set null something already null, it will break any putIfUntouched() which saw the first null.
 // This could result in write contention starving out a real write.  The solution is to only reset things
 // that are not already null.
 final Map < Key , Object > cached = this . cacheGetAll ( bad ) ; // Remove the stuff we don't care about
 cached . values ( ) . removeIf ( Objects :: isNull ) ; this . empty ( cached . keySet ( ) ) ; } }
Update a set of buckets with new values.  If collisions occur, resets the memcache value to null.

@param updates can have null Entity values, which will record a negative cache result.  Buckets must have
been obtained from getAll().
Update a set of buckets with new values . If collisions occur resets the memcache value to null .