public Tuple <Dictionary <long, long>, List <long>, List <long> > ApplyUpdate(Delta delta) { rwLock.EnterWriteLock(); try { Dictionary <DMSType, int> counters = new Dictionary <DMSType, int>(this.counters); Dictionary <long, long> ids = delta.ResolveIds(x => counters.ContainsKey(x) ? (counters[x] = counters[x] + 1) : -1); if (ids == null) { return(null); } delta.SortOperations(); HashSet <long> toValidate = new HashSet <long>(); List <IdentifiedObject> inserted = new List <IdentifiedObject>(); List <IdentifiedObject> updatedOld = new List <IdentifiedObject>(); List <IdentifiedObject> updatedNew = new List <IdentifiedObject>(); List <IdentifiedObject> deleted = new List <IdentifiedObject>(); Func <long, IdentifiedObject> entityGetter = x => { IdentifiedObject y; TryGetEntity(x, out y); return(y); }; foreach (ResourceDescription rd in delta.InsertOperations) { IdentifiedObject io = InsertEntity(rd); if (io == null) { return(null); } toValidate.Add(io.GID); io.GetEntitiesToValidate(entityGetter, toValidate); inserted.Add(io); } foreach (ResourceDescription rd in delta.UpdateOperations) { Tuple <IdentifiedObject, IdentifiedObject> io = UpdateEntity(rd); if (io == null) { return(null); } toValidate.Add(io.Item1.GID); io.Item1.GetEntitiesToValidate(entityGetter, toValidate); io.Item2.GetEntitiesToValidate(entityGetter, toValidate); updatedOld.Add(io.Item1); updatedNew.Add(io.Item2); } foreach (ResourceDescription rd in delta.DeleteOperations) { IdentifiedObject io = DeleteEntity(rd); if (io == null) { return(null); } toValidate.Add(io.GID); io.GetEntitiesToValidate(entityGetter, toValidate); deleted.Add(io); } foreach (long gid in toValidate) { IdentifiedObject io; if (!TryGetEntity(gid, out io)) { continue; } if (!io.Validate(entityGetter)) { return(null); } } if (db != null) { this.inserted = inserted; this.updatedOld = updatedOld; this.updatedNew = updatedNew; this.deleted = deleted; this.oldCounters = this.counters; } this.counters = counters; return(new Tuple <Dictionary <long, long>, List <long>, List <long> >(ids, updatedOld.Select(x => x.GID).ToList(), deleted.Select(x => x.GID).ToList())); } finally { rwLock.ExitWriteLock(); } }