/// <summary> /// Split a transaction request between multiple shards /// </summary> /// <param name="serverSelector">a functions that gives the shard index for a primary key</param> /// <param name="serverCount">the total number of shards</param> /// <returns></returns> public SafeDictionary <int, TransactionRequest> SplitByServer([NotNull] Func <KeyValue, int> serverSelector, int serverCount) { if (serverSelector == null) { throw new ArgumentNullException(nameof(serverSelector)); } var result = new SafeDictionary <int, TransactionRequest>(() => new TransactionRequest { TransactionId = TransactionId }); foreach (var childRequest in ChildRequests) { TransactionRequest transactionRequest; int shard = 0; switch (childRequest) { // simple put requests contain ore or more items from the same collection and no condition case PutRequest simplePutRequest when !simplePutRequest.HasCondition: var byServer = simplePutRequest.SplitByServer(serverSelector); foreach (var pair in byServer) { transactionRequest = result.GetOrCreate(pair.Key); transactionRequest.ChildRequests.Add(pair.Value); } break; // a put request with a condition. It can contain a single item case PutRequest conditionalUpdate when conditionalUpdate.HasCondition: shard = serverSelector(conditionalUpdate.Items.Single().PrimaryKey); transactionRequest = result.GetOrCreate(shard); transactionRequest.ChildRequests.Add(conditionalUpdate); break; // a simple delete request contains one object to be deleted case RemoveRequest simpleDeleteRequest: shard = serverSelector(simpleDeleteRequest.PrimaryKey); transactionRequest = result.GetOrCreate(shard); transactionRequest.ChildRequests.Add(simpleDeleteRequest); break; // a delete many request contains a predicate that needs to be send to all servers case RemoveManyRequest deleteMany: for (int i = 0; i < serverCount; i++) { transactionRequest = result.GetOrCreate(i); transactionRequest.ChildRequests.Add(deleteMany); } break; } } return(result); }
public void AddToSession(Guid sessionId, IList <PackedObject> objects) { var list = _objectsBySession.GetOrCreate(sessionId); lock (list) { list.AddRange(objects); } }
private ServerSideLock Lock(string name) { return(_locksByCollection.GetOrCreate(name)); }