public IDictionary <Number640, Enum> PutAll(SortedDictionary <Number640, Data> dataMap, IPublicKey publicKey, bool putIfAbsent, bool domainProtection, bool sendSelf) { if (dataMap.Count == 0) { return(Convenient.EmptyDictionary <Number640, Enum>()); } var min = dataMap.First().Key; // TODO check if correct var max = dataMap.Last().Key; var retVal = new Dictionary <Number640, Enum>(); var keysToCheck = new HashSet <Number480>(); var rangeLock = Lock(min, max); try { foreach (var kvp in dataMap) { var key = kvp.Key; keysToCheck.Add(key.LocationAndDomainAndContentKey); var newData = kvp.Value; if (!SecurityDomainCheck(key.LocationAndDomainKey, publicKey, publicKey, domainProtection)) { retVal.Add(key, PutStatus.FailedSecurity); continue; } // We need this check in case we did not use the encoder/deconder, // which is the case if we send the message to ourself. In that // case, the public key of the data is never set to the message // publick key, if the publick key of the data was null. IPublicKey dataKey; if (sendSelf && newData.PublicKey == null) { dataKey = publicKey; } else { dataKey = newData.PublicKey; } if (!SecurityEntryCheck(key.LocationAndDomainAndContentKey, publicKey, dataKey, newData.IsProtectedEntry)) { retVal.Add(key, PutStatus.FailedSecurity); continue; } var contains = _backend.Contains(key); if (contains) { if (putIfAbsent) { retVal.Add(key, PutStatus.FailedNotAbsent); continue; } var oldData = _backend.Get(key); if (oldData.IsDeleted) { retVal.Add(key, PutStatus.Deleted); continue; } if (!oldData.BasedOnSet.Equals(newData.BasedOnSet)) { retVal.Add(key, PutStatus.VersionFork); continue; } } var oldData2 = _backend.Put(key, newData); long expiration = newData.ExpirationMillis; // handle timeout _backend.AddTimeout(key, expiration); if (newData.HasPrepareFlag) { retVal.Add(key, PutStatus.OkPrepared); } else { if (newData.Equals(oldData2)) { retVal.Add(key, PutStatus.OkUnchanged); } else { retVal.Add(key, PutStatus.Ok); } } } //now check for forks foreach (var key in keysToCheck) { var minVersion = new Number640(key, Number160.Zero); var maxVersion = new Number640(key, Number160.MaxValue); var tmp = _backend.SubMap(minVersion, maxVersion, -1, true); var heads = GetLatestInternal(tmp); if (heads.Count > 1) { foreach (var fork in heads.Keys) { if (retVal.ContainsKey(fork)) { retVal.Add(fork, PutStatus.VersionFork); } } } } return(retVal); } finally { rangeLock.Unlock(); } }