zoukankan      html  css  js  c++  java
  • 《Redis实战》-Josiah L.Carlson 的python的源代码翻译成C# 第二章

        class TestCh02
        {
            public int LIMIT = 10000000;
            public bool QUIT = false;
    
            CSRedisClient _conn;
            public TestCh02()
            {
                _conn = new CSRedis.CSRedisClient("127.0.0.1:6379,defaultDatabase=14,poolsize=500,ssl=false,writeBuffer=10240");
            }
    
            public string check_token(CSRedisClient conn, string token)
            {
                return conn.HGet("login:", token);
            }
    
            public void update_token(CSRedisClient conn, string token, string user, string item = null)
            {
                var timestamp = (DateTime.Now - new DateTime(1970, 1, 1)).TotalSeconds;
                conn.HSet("login:", token, user);
                conn.ZAdd("recent:", ((decimal)timestamp, token));
                if (!string.IsNullOrEmpty(item))
                {
                    conn.ZAdd("viewed:" + token, ((decimal)timestamp, item));
                    conn.ZRemRangeByRank("viewed:" + token, 0, -26);
                    conn.ZIncrBy("viewed:", item, -1);
                }
            }
    
            public void clean_sessions(object obj)
            {
                CSRedisClient conn = obj as CSRedisClient;
                while (!QUIT)
                {
                    var size = conn.ZCard("recent:");
                    if (size <= LIMIT)
                    {
                        Thread.Sleep(1000);
                        continue;
                    }
    
                    var end_index = Math.Min(size - LIMIT, 100);
                    var tokens = conn.ZRange("recent:", 0, end_index - 1);
    
                    List<string> session_keys = new List<string>();
                    foreach (var token in tokens)
                    {
                        session_keys.Add("viewed:" + token);
                    }
    
                    conn.Del(session_keys.ToArray());
                    conn.HDel("login:", tokens);
                    conn.ZRem("recent:", tokens);
                }
            }
    
            public void add_to_cart(CSRedisClient conn, string session, string item, int count)
            {
                if (count <= 0)
                    conn.HDel("cart:" + session, item);
                else
                    conn.HSet("cart:" + session, item, count);
            }
    
            public void clean_full_sessions(object obj)
            {
                CSRedisClient conn = obj as CSRedisClient;
                while (!QUIT)
                {
                    var size = conn.ZCard("recent:");
                    if (size <= LIMIT)
                    {
                        Thread.Sleep(1000);
                        continue;
                    }
    
                    var end_index = Math.Min(size - LIMIT, 100);
                    var sessions = conn.ZRange("recent:", 0, end_index - 1);
    
                    List<string> session_keys = new List<string>();
                    foreach (var sess in sessions)
                    {
                        session_keys.Add("viewed:" + sess);
                        session_keys.Add("cart:" + sess);
                    }
    
                    conn.Del(session_keys.ToArray());
                    conn.HDel("login:", sessions);
                    conn.ZRem("recent:", sessions);
                }
            }
    
            public string cache_request(CSRedisClient conn, string request, Func<string, string> callback)
            {
                if (!can_cache(conn, request))
                {
                    return callback(request); ;
                }
    
                var page_key = "cache:" + hash_request(request);
                var content = conn.Get(page_key);
    
                if (string.IsNullOrEmpty(content))
                {
                    content = callback(request);
                    conn.Set(page_key, content, 300);
                }
    
                return content;
            }
    
            public void schedule_row_cache(CSRedisClient conn, string row_id, int delay)
            {
                conn.ZAdd("delay:", (delay, row_id));
                conn.ZAdd("schedule:", ((decimal)(DateTime.Now - new DateTime(1970, 1, 1)).TotalSeconds, row_id));
            }
    
            public void cache_rows(object obj)
            {
                CSRedisClient conn = obj as CSRedisClient;
                while (!QUIT)
                {
                    var next = conn.ZRangeWithScores("schedule:", 0, 0);
                    var now = (DateTime.Now - new DateTime(1970, 1, 1)).TotalSeconds;
                    if (next != null && next[0].score > (decimal)now)
                    {
                        Thread.Sleep(50);
                        continue;
                    }
    
                    var row_id = next[0].member;
                    var delay = conn.ZScore("delay:", row_id) ?? 0;
                    if (delay <= 0)
                    {
                        conn.ZRem("delay:", row_id);
                        conn.ZRem("schedule:", row_id);
                        conn.Del("inv:" + row_id);
                    }
    
                    var row = new Inventory(row_id);
                    conn.ZAdd("schedule:", ((decimal)now + delay, row_id));
                    conn.Set("inv:" + row_id, Newtonsoft.Json.JsonConvert.SerializeObject(row.to_dict()));
                }
            }
    
            public void rescale_viewed(CSRedisClient conn)
            {
                while (!QUIT)
                {
                    conn.ZRemRangeByRank("viewed:", 20000, -1);
                    conn.ZInterStore("viewed:", new decimal[] { (decimal)0.5 }, RedisAggregate.Max, "viewed:");
                    Thread.Sleep(300000);
                }
            }
    
            public bool can_cache(CSRedisClient conn, string request)
            {
                var item_id = extract_item_id(request);
                if (string.IsNullOrEmpty(item_id) || is_dynamic(request))
                    return false;
    
                var rank = conn.ZRank("viewed:", item_id);
    
                return rank.HasValue && rank.Value < 10000;
            }
    
            public string extract_item_id(string request)
            {
                NameValueCollection nameValueCollection;
                string url;
                UrlHelper.ParseUrl(request, out url, out nameValueCollection);
                return nameValueCollection.Get("item");
            }
    
            public bool is_dynamic(string request)
            {
                NameValueCollection nameValueCollection;
                string url;
                UrlHelper.ParseUrl(request, out url, out nameValueCollection);
                return !string.IsNullOrEmpty(nameValueCollection.Get("_"));
            }
    
            public string hash_request(string request)
            {
                return request.GetHashCode().ToString();
            }
    
            public void tearDown()
            {
                var conn = _conn;
                var to_del = conn.Keys("login:*").Union(conn.Keys("recent:*")).Union(conn.Keys("viewed:*")).Union(conn.Keys("cart:*")).Union(conn.Keys("cache:*")).Union(conn.Keys("delay:*")).Union(conn.Keys("schedule:*")).Union(conn.Keys("inv:*")).ToArray();
                conn.Del(to_del);
    
                QUIT = false;
                LIMIT = 10000000;
            }
    
            public void test_login_cookies()
            {
                var conn = _conn;
                var token = Guid.NewGuid().ToString();
    
                update_token(conn, token, "username", "itemX");
                Console.WriteLine("We just logged-in/updated token:" + token);
                Console.WriteLine("For user:" + "username");
                Console.WriteLine();
    
                Console.WriteLine("What username do we get when we look-up that token?");
                var r = check_token(conn, token);
                Console.WriteLine(r);
                Console.WriteLine();
    
                Console.WriteLine("Let's drop the maximum number of cookies to 0 to clean them out");
                Console.WriteLine("We will start a thread to do the cleaning, while we stop it later");
    
                LIMIT = 0;
                Thread thread = new Thread(new ParameterizedThreadStart(clean_sessions));//创建线程
                thread.Start(conn);                                                           //启动线程
                Thread.Sleep(1000);
                QUIT = true;
                Thread.Sleep(2000);
    
                var s = conn.HLen("login:");
                Console.WriteLine("The current number of sessions still available is:" + s);
            }
    
            public void test_shopping_cart_cookies()
            {
                var conn = _conn;
                var token = Guid.NewGuid().ToString();
    
                Console.WriteLine("We'll refresh our session...");
                update_token(conn, token, "username", "itemX");
                Console.WriteLine("And add an item to the shopping cart");
                add_to_cart(conn, token, "itemY", 3);
                var r = conn.HGetAll("cart:" + token);
                Console.WriteLine("Our shopping cart currently has:" + PrintHelper.Dictionary2String(r));
                Console.WriteLine();
    
                Console.WriteLine("Let's clean out our sessions and carts");
    
                LIMIT = 0;
                Thread thread = new Thread(new ParameterizedThreadStart(clean_full_sessions));//创建线程
                thread.Start(conn);                                                           //启动线程
                Thread.Sleep(1000);
                QUIT = true;
                Thread.Sleep(2000);
    
                r = conn.HGetAll("cart:" + token);
                Console.WriteLine("Our shopping cart now contains:" + PrintHelper.Dictionary2String(r));
            }
    
            public void test_cache_request()
            {
                var conn = _conn;
                var token = Guid.NewGuid().ToString();
    
                Func<string, string> callback = (request) => { return "content for " + request; };
    
                update_token(conn, token, "username", "itemX");
                var url = "http://test.com/?item=itemX";
                Console.WriteLine("We are going to cache a simple request against" + url);
                var result = cache_request(conn, url, callback);
                Console.WriteLine("We got initial content:" + result);
                Console.WriteLine();
    
                Console.WriteLine("To test that we've cached the request, we'll pass a bad callback");
                var result2 = cache_request(conn, url, null);
                Console.WriteLine("We ended up getting the same response!" + result2);
    
            }
    
            public void test_cache_rows()
            {
                var conn = _conn;
    
                Console.WriteLine("First, let's schedule caching of itemX every 5 seconds");
                schedule_row_cache(conn, "itemX", 5);
                Console.WriteLine("Our schedule looks like:");
                var s = conn.ZRangeWithScores("schedule:", 0, -1);
                Console.WriteLine(PrintHelper.ValueTuple2String(s));
    
                Console.WriteLine("We'll start a caching thread that will cache the data...");
                Thread thread = new Thread(new ParameterizedThreadStart(cache_rows));
                thread.Start(conn);
                Thread.Sleep(1000);
                Console.WriteLine("Our cached data looks like:");
                var r = conn.Get("inv:itemX");
                Console.WriteLine(r);
                Console.WriteLine();
                Console.WriteLine("We'll check again in 5 seconds...");
                Thread.Sleep(5000);
                Console.WriteLine("Notice that the data has changed...");
                var r2 = conn.Get("inv:itemX");
                Console.WriteLine(r2);
                Console.WriteLine();
    
                Console.WriteLine("Let's force un-caching");
                schedule_row_cache(conn, "itemX", -1);
                Thread.Sleep(1000);
                r = conn.Get("inv:itemX");
                Console.WriteLine("The cache was cleared?" + r);
                Console.WriteLine();
    
                QUIT = true;
                Thread.Sleep(2000);
            }
    
        }
    
        public class Inventory
        {
            public string id { get; set; }
            public string data { get; set; }
            public decimal cached { get; set; }
            public Inventory(string id)
            {
                this.id = id;
            }
    
            public Inventory get(string id)
            {
                return new Inventory(id);
            }
    
            public Dictionary<string, object> to_dict()
            {
                return new Dictionary<string, object>()
                {
                    { "id", this.id },
                    { "data", "data to cache..."},
                    { "cached", (decimal)(DateTime.Now - new DateTime(1970, 1, 1)).TotalSeconds },
                };
            }
    
    
    
        }
    
        public class UrlHelper
        {
            /// <summary>
            /// 分析 url 字符串中的参数信息
            /// </summary>
            /// <param name="url">输入的 URL</param>
            /// <param name="baseUrl">输出 URL 的基础部分</param>
            /// <param name="nvc">输出分析后得到的 (参数名,参数值) 的集合</param>
            public static void ParseUrl(string url, out string baseUrl, out NameValueCollection nvc)
            {
                if (url == null)
                    throw new ArgumentNullException("url");
                nvc = new NameValueCollection();
                baseUrl = "";
                if (url == "")
                    return;
                int questionMarkIndex = url.IndexOf('?');
                if (questionMarkIndex == -1)
                {
                    baseUrl = url;
                    return;
                }
                baseUrl = url.Substring(0, questionMarkIndex);
                if (questionMarkIndex == url.Length - 1)
                    return;
                string ps = url.Substring(questionMarkIndex + 1);
                // 开始分析参数对  
                Regex re = new Regex(@"(^|&)?(w+)=([^&]+)(&|$)?", RegexOptions.Compiled);
                MatchCollection mc = re.Matches(ps);
                foreach (Match m in mc)
                {
                    nvc.Add(m.Result("$2").ToLower(), m.Result("$3"));
                }
            }
    
        }
    View Code

    源码码下载地址 AIStudio.ConSole.Redis (gitee.com)

    作者:竹天笑
    互相学习,提高自己。
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
  • 相关阅读:
    xml配置文件使用-读取、转换
    .NET 4.0 缓存
    jQuery分页插件pagination.js 笔记
    Spring源码
    Shell编程(字符串篇)
    Linux DNS 相关
    Shell将命令执行结果写入文件
    Linux安装GCC
    Linux网络安全
    产品经理基础
  • 原文地址:https://www.cnblogs.com/akwkevin/p/14064146.html
Copyright © 2011-2022 走看看