T IPayloadCache.GetOrAddPayload <T>(PayloadFactory <T> payloadFactory) { try { IPayloadValue <T> payload = null; IPayloadCollection currentCollection; do { T existingValue; if (_collection.TryGetPayload(out existingValue)) { return(existingValue); } IPayloadValue <T> contextProperty = payload ?? (payload = new PayloadValue <T>(payloadFactory())); currentCollection = Volatile.Read(ref _collection); Interlocked.CompareExchange(ref _collection, currentCollection.Add(contextProperty), currentCollection); }while (currentCollection == Volatile.Read(ref _collection)); return(payload.Value); } catch (Exception exception) { throw new PayloadFactoryException($"The payload factory faulted: {TypeCache<T>.ShortName}", exception); } }
ArrayPayloadCollection(IReadOnlyPayloadCollection parent, IPayloadValue payload, IPayloadValue[] payloads) : base(parent) { _parent = parent; _payloads = new IPayloadValue[payloads.Length + 1]; _payloads[0] = payload; Array.Copy(payloads, 0, _payloads, 1, payloads.Length); }
T IPayloadCache.AddOrUpdatePayload <T>(PayloadFactory <T> addFactory, UpdatePayloadFactory <T> updateFactory) { try { T previousValue = null; IPayloadValue <T> context = null; IPayloadCollection currentCollection; do { if (_collection.TryGetPayload(out T existingValue)) { if (context == null || previousValue != existingValue) { context = new PayloadValue <T>(updateFactory(existingValue)); } previousValue = existingValue; currentCollection = Volatile.Read(ref _collection); Interlocked.CompareExchange(ref _collection, currentCollection.Add(context), currentCollection); } else { if (context == null) { context = new PayloadValue <T>(addFactory()); } currentCollection = Volatile.Read(ref _collection); Interlocked.CompareExchange(ref _collection, currentCollection.Add(context), currentCollection); } }while (currentCollection == Volatile.Read(ref _collection)); return(context.Value); } catch (Exception exception) { throw new PayloadFactoryException($"The payload factory faulted: {TypeCache<T>.ShortName}", exception); } }
public override IPayloadCollection Add(IPayloadValue payload) { return(new ArrayPayloadCollection(_parent, payload, _payloads)); }
public override IPayloadCollection Add(IPayloadValue payload) { return(new SinglePayloadCollection(payload, Parent)); }
public SinglePayloadCollection(IPayloadValue payload, IReadOnlyPayloadCollection parent = null) : base(parent) { _payload = payload; _parent = parent; }
public abstract IPayloadCollection Add(IPayloadValue payload);