Пример #1
0
        /// <summary>
        /// This method executes the given delegate on a socket from the server that corresponds to the given hash.
        /// If anything causes an error, the given defaultValue will be returned instead.
        /// This method takes care of disposing the socket properly once the delegate has executed.
        /// </summary>
        internal T Execute <T>(uint hash, T defaultValue, UseSocket <T> use)
        {
            SocketPool pool = GetSocketPool(hash);

            if (pool.socketPoolBak == null && serverPoolBak != null)
            {
                //为主Socket池挂接备份的Socket池
                pool.socketPoolBak = serverPoolBak.GetSocketPool(hash);
            }
            return(Execute(pool, defaultValue, use));
        }
        private object[] get(string command, string[] keys, bool keysAreChecked, uint[] hashes, out ulong[] uniques)
        {
            //Check arguments.
            if (keys == null || hashes == null)
            {
                throw new ArgumentException("Keys and hashes arrays must not be null.");
            }
            if (keys.Length != hashes.Length)
            {
                throw new ArgumentException("Keys and hashes arrays must be of the same length.");
            }
            uniques = new ulong[keys.Length];

            //Avoid going through the server grouping if there's only one key.
            if (keys.Length == 1)
            {
                return(new object[] { get(command, keys[0], keysAreChecked, hashes[0], out uniques[0]) });
            }

            //Check keys.
            if (!keysAreChecked)
            {
                for (int i = 0; i < keys.Length; i++)
                {
                    checkKey(keys[i]);
                }
            }

            //Group the keys/hashes by server(pool)
            Dictionary <SocketPool, Dictionary <string, List <int> > > dict = new Dictionary <SocketPool, Dictionary <string, List <int> > >();

            for (int i = 0; i < keys.Length; i++)
            {
                Dictionary <string, List <int> > getsForServer;
                SocketPool pool = serverPool.GetSocketPool(hashes[i]);
                if (!dict.TryGetValue(pool, out getsForServer))
                {
                    dict[pool] = getsForServer = new Dictionary <string, List <int> >();
                }

                List <int> positions;
                if (!getsForServer.TryGetValue(keys[i], out positions))
                {
                    getsForServer[keyPrefix + keys[i]] = positions = new List <int>();
                }
                positions.Add(i);
            }

            //Get the values
            object[] returnValues = new object[keys.Length];
            ulong[]  _uniques     = new ulong[keys.Length];
            foreach (KeyValuePair <SocketPool, Dictionary <string, List <int> > > kv in dict)
            {
                serverPool.Execute(kv.Key, delegate(PooledSocket socket)
                {
                    //Build the get request
                    StringBuilder getRequest = new StringBuilder(command);
                    foreach (KeyValuePair <string, List <int> > key in kv.Value)
                    {
                        getRequest.Append(" ");
                        getRequest.Append(key.Key);
                    }
                    getRequest.Append("\r\n");

                    //Send get request
                    socket.Write(getRequest.ToString());

                    //Read values, one by one
                    object gottenObject;
                    string gottenKey;
                    ulong unique;
                    while (readValue(socket, out gottenObject, out gottenKey, out unique))
                    {
                        foreach (int position in kv.Value[gottenKey])
                        {
                            returnValues[position] = gottenObject;
                            _uniques[position]     = unique;
                        }
                    }
                });
            }
            uniques = _uniques;
            return(returnValues);
        }