public void PutAll(IDictionary <K, V> m)
        {
            var partitionService = GetContext().GetPartitionService();
            var partitions       = new Dictionary <int, IDictionary <IData, IData> >(partitionService.GetPartitionCount());

            foreach (var kvp in m)
            {
                var keyData = ToData(kvp.Key);
                InvalidateNearCacheEntry(keyData);
                var partitionId = partitionService.GetPartitionId(keyData);
                IDictionary <IData, IData> partition = null;
                if (!partitions.TryGetValue(partitionId, out partition))
                {
                    partition = new Dictionary <IData, IData>();
                    partitions[partitionId] = partition;
                }
                partition[keyData] = ToData(kvp.Value);
            }

            var futures = new List <IFuture <IClientMessage> >(partitions.Count);

            foreach (var kvp in partitions)
            {
                var request = MapPutAllCodec.EncodeRequest(GetName(), kvp.Value);
                var future  = GetContext().GetInvocationService().InvokeOnPartition(request, kvp.Key);
                futures.Add(future);
            }
            ThreadUtil.GetResult(futures);
        }
        Task SetAsync(Dictionary <Guid, Dictionary <int, List <KeyValuePair <IData, IData> > > > ownerEntries, CancellationToken cancellationToken)
        {
            // see comments on the base Map class
            // this should be no different except for this entry invalidation method,
            // added as a continuation to each task that is being created

            void InvalidateEntries(IEnumerable <KeyValuePair <IData, IData> > list)
            {
                foreach (var(key, _) in list)
                {
                    _cache.Remove(key);
                }
            }

            var tasks = new List <Task>();

            foreach (var(ownerId, part) in ownerEntries)
            {
                foreach (var(partitionId, list) in part)
                {
                    if (list.Count == 0)
                    {
                        continue;
                    }

                    var requestMessage = MapPutAllCodec.EncodeRequest(Name, list, false);
                    requestMessage.PartitionId = partitionId;
                    var ownerTask = Cluster.Messaging.SendToMemberAsync(requestMessage, ownerId, cancellationToken)
                                    .ContinueWith(_ => InvalidateEntries(list), default, default, TaskScheduler.Current);
        protected virtual void PutAllInternal(IDictionary <TKey, TValue> map,
                                              Dictionary <int, IDictionary <IData, IData> > partitions)
        {
            var futures = new List <IFuture <IClientMessage> >(partitions.Count);

            foreach (var kvp in partitions)
            {
                var request = MapPutAllCodec.EncodeRequest(GetName(), kvp.Value.ToList());
                var future  = GetContext().GetInvocationService().InvokeOnPartition(request, kvp.Key);
                futures.Add(future);
            }
            ThreadUtil.GetResult(futures);
        }
예제 #4
0
        protected virtual void PutAllInternal(List <KeyValuePair <IData, IData> >[] partitions)
        {
            var futures = new ConcurrentQueue <IFuture <ClientMessage> >();

            Parallel.For(0, partitions.Length, i =>
            {
                var entries = partitions[i];
                if (entries.Count > 0)
                {
                    var request = MapPutAllCodec.EncodeRequest(Name, entries);
                    var future  = Client.InvocationService.InvokeOnPartitionOwner(request, i);
                    futures.Enqueue(future);
                }
            });
            GetResult(futures);
        }
예제 #5
0
        protected virtual void PutAllInternal(IDictionary <TKey, TValue> map, ArrayList partitions)
        {
            var futures = new ConcurrentQueue <IFuture <IClientMessage> >();

            Parallel.For(0, partitions.Count, i =>
            {
                var entries = (ArrayList)partitions[i];
                if (entries.Count > 0)
                {
                    var request = MapPutAllCodec.EncodeRequest(GetName(), entries);
                    var future  = GetContext().GetInvocationService().InvokeOnPartition(request, i);
                    futures.Enqueue(future);
                }
            });
            ThreadUtil.GetResult(futures);
        }
        Task SetAsync(Dictionary <Guid, Dictionary <int, List <KeyValuePair <IData, IData> > > > ownerEntries, CancellationToken cancellationToken)
        {
            // TODO: add a SendAsync(...) to Cluster/Client
            // that can send multiple messages and use one single completion source
            // cannot inherit from TaskCompletionSource: it's not sealed but nothing is virtual

            // create parallel tasks to fire requests for each owner (each network client)
            // for each owner, serialize requests for each partition, because each message
            // needs to have its own partition id
            var tasks = new List <Task>();

            foreach (var(ownerId, part) in ownerEntries)
            {
                foreach (var(partitionId, list) in part)
                {
                    if (list.Count == 0)
                    {
                        continue;
                    }

                    var requestMessage = MapPutAllCodec.EncodeRequest(Name, list, false);
                    requestMessage.PartitionId = partitionId;
                    var ownerTask = Cluster.Messaging.SendToMemberAsync(requestMessage, ownerId, cancellationToken);
                    tasks.Add(ownerTask);
                }
            }

            // and wait on all tasks, ignoring the responses
            var task = Task.WhenAll(tasks);

#if HZ_OPTIMIZE_ASYNC
            return(task);
#else
            await task.CfAwait();
#endif
        }