@VisibleForTesting
	protected CounterDataGetCreateContainer getOrCreateCounterData(final String counterName)
	{
		// Validation failures will throw an exception. See JavaDoc for details.
		this.counterNameValidator.validateCounterName(counterName);

		final Key<CounterData> counterKey = CounterData.key(counterName);

		// This get/create is acceptable to perform outside of a transaction. In certain edge-cases, it's possible
		// that two threads might call this operation at the same time, and one or both threads might think (errantly)
		// that no CounterData exists in the Datastore when in reality one of the threads (or some other thread) may
		// have created the CoutnerData already. However, in this case, the two create operations will be the same using
		// default data, so even though the "winner" will be random, the result will be the same. In future, this
		// assumption may need to change.
		CounterData counterData = ObjectifyService.ofy().load().key(counterKey).now();
		if (counterData == null)
		{
			counterData = new CounterData(counterName, config.getNumInitialShards());
			// counterData.setNegativeCountAllowed(config.isNegativeCountAllowed());
			ObjectifyService.ofy().save().entity(counterData).now();
			return new CounterDataGetCreateContainer(counterData, NEW_COUNTER_CREATED);
		}
		else
		{
			return new CounterDataGetCreateContainer(counterData, COUNTER_EXISTED);
		}
	}
@ VisibleForTesting protected CounterDataGetCreateContainer getOrCreateCounterData ( final String counterName ) { this . counterNameValidator . validateCounterName ( counterName ) ; final Key < CounterData > counterKey = CounterData . key ( counterName ) ; CounterData counterData = ObjectifyService . ofy ( ) . load ( ) . key ( counterKey ) . now ( ) ; if ( counterData == null ) { counterData = new CounterData ( counterName , config . getNumInitialShards ( ) ) ; ObjectifyService . ofy ( ) . save ( ) . entity ( counterData ) . now ( ) ; return new CounterDataGetCreateContainer ( counterData , NEW_COUNTER_CREATED ) ; } else { return new CounterDataGetCreateContainer ( counterData , COUNTER_EXISTED ) ; } }
Helper method to get (or create and then get) a {@link CounterData} from the Datastore with a given name. The
result of this function is guaranteed to be non-null if no exception is thrown.

@param counterName
@return
@throws NullPointerException if the {@code counterName} is null.
@throws InvalidCounterNameException If the counter name is too long or too short.