예제 #1
0
파일: Main.cs 프로젝트: benapetr/memcached
        /// <summary>
        /// Reloads the users.
        /// </summary>
        /// <param name="o">O.</param>
        /// <param name="e">E.</param>
        public static void ReloadUsers(object o, EventArgs e)
        {
            if (!File.Exists(Configuration.UserDB))
            {
                DebugLog("There is no user db to load users from");
                return;
            }
            DebugLog("Reloading users");
            List<string> lines = new List<string>();
            lines.AddRange(File.ReadAllLines(Configuration.UserDB));
            lock (GlobalCaches)
            {
                List<User> remove = new List<User>();
                foreach (User user in GlobalCaches.Keys)
                {
                    if (user.username != ":global")
                    {
                        remove.Add(user);
                    }
                }

                foreach (string user in lines)
                {
                    if (user.Contains (":"))
                    {
                        string name = user.Substring(0, user.IndexOf (":"));
                        string pw = user.Substring(user.IndexOf (":") + 1);
                        User xx =  getUser(name);
                        if (xx == null)
                        {
                            xx = new User(name);
                            xx.password = pw;
                            GlobalCaches.Add (xx, new Cache());
                            DebugLog("Created cache: " + name);
                        } else
                        {
                            remove.Remove(xx);
                        }
                    }
                    else
                    {
                        DebugLog("Invalid record: " + user);
                    }
                }

                foreach (User c in remove)
                {
                    DebugLog("Removing: " + c.username);
                    GlobalCaches.Remove(c);
                }
            }
        }
예제 #2
0
파일: Main.cs 프로젝트: benapetr/memcached
 /// <summary>
 /// Loads the users.
 /// </summary>
 public static void LoadUsers()
 {
     watcher = new FileSystemWatcher();
     watcher.Path = Configuration.Path;
     string filename = Configuration.UserDB;
     if (filename.Contains (Path.DirectorySeparatorChar.ToString()))
     {
         filename = filename.Substring (filename.LastIndexOf(Path.DirectorySeparatorChar.ToString()) +1 );
     }
     watcher.Filter = filename;
     watcher.Changed += new FileSystemEventHandler(ReloadUsers);
     watcher.Created += new FileSystemEventHandler(ReloadUsers);
     watcher.EnableRaisingEvents = true;
     if (!File.Exists(Configuration.UserDB))
     {
         DebugLog("There is no user db to load users from");
         return;
     }
     List<string> lines = new List<string>();
     lines.AddRange(File.ReadAllLines(Configuration.UserDB));
     lock (GlobalCaches)
     {
         foreach (string i in lines)
         {
             if (i.Contains (":"))
             {
                 string name = i.Substring(0, i.IndexOf (":"));
                 string pw = i.Substring(i.IndexOf (":") + 1);
                 User user = new User(name);
                 user.password = pw;
                 GlobalCaches.Add (user, new Cache());
                 DebugLog("User: "******"Invalid record: " + i);
             }
         }
     }
 }
예제 #3
0
파일: Main.cs 프로젝트: benapetr/memcached
 /// <summary>
 /// The entry point of the program, where the program control starts and ends.
 /// </summary>
 /// <param name="args">The command-line arguments.</param>
 public static void Main(string[] args)
 {
     Configuration.Path = Directory.GetCurrentDirectory();
     if (!Terminal.Parse (args))
     {
         Log ("Starting sharp memcached server version " + Configuration.Version);
         st = DateTime.Now;
         if (Configuration.Verbosity > 0)
         {
             DebugLog ("Verbosity: " + Configuration.Verbosity.ToString());
         }
         if (!Configuration.UDP && !Configuration.TCP)
         {
             Log ("ERROR: you must enable either tcp or udp");
             return;
         }
         Configuration.InstanceMemoryLimitByteSize = (ulong)Configuration.InstanceMemoryLimit * 1024 * 1024;
         Configuration.GlobalMemoryLimitByteSize = (ulong)Configuration.GlobalMemoryLimit * 1024 * 1024;
         Thread cleaner = new Thread(GC);
         cleaner.Start();
         // we have 1 shared cache for everyone
         GlobalUser = new User(":global");
         GlobalCaches.Add (GlobalUser, new Cache());
         LoadUsers();
         // create a new thread for tcp and start it
         Thread tcp = new Thread(Memcache.ListenTCP);
         tcp.Name = "tcp listener";
         tcp.Start();
         Thread udp = new Thread(Memcache.ListenUDP);
         udp.Name = "udp listener";
         udp.Start();
         while (isRunning)
         {
             Thread.Sleep(100);
         }
     }
 }
예제 #4
0
        private static void Stats(string parameters, ref System.IO.StreamWriter w, User user)
        {
            if (parameters == "")
            {
                Cache cache;
                lock (MainClass.GlobalCaches)
                {
                    cache = MainClass.GlobalCaches[user];
                }
                Send ("STAT pid " + System.Diagnostics.Process.GetCurrentProcess ().Id.ToString (), ref w);
                Send ("STAT uptime " + MainClass.uptime ().ToString (), ref w);
                Send ("STAT time " + ToUnix().ToString(), ref w);
                Send ("STAT version sharp-memcached" + Configuration.Version, ref w);
                Send ("STAT pointer_size " + (IntPtr.Size * 8).ToString(), ref w);
                Send ("STAT global_memory_limit " + Configuration.GlobalMemoryLimitByteSize.ToString(), ref w);
                Send ("STAT user_memory_limit " + Configuration.InstanceMemoryLimitByteSize.ToString(), ref w);
                Send ("STAT hash_bytes_local " + cache.Size.ToString(), ref w);
                Send ("STAT user " + user.username, ref w);
                Send ("STAT hash_bytes " + Cache.GlobalSize.ToString(), ref w);
                Send ("STAT hashtables " + MainClass.GlobalCaches.Count.ToString (), ref w);
                Send ("STAT curr_items " + cache.Count().ToString(), ref w);
                Send ("STAT total_connections " + MainClass.Connections.ToString (), ref w);
                Send ("STAT curr_connections " + MainClass.OpenConnections.ToString (), ref w);
                Send ("STAT cmd_get " + cache.cmd_get.ToString(), ref w);
                Send ("STAT cmd_set " + cache.cmd_set.ToString (), ref w);
                Send ("STAT cmd_flush " + cache.cmd_flush.ToString(), ref w);
                Send ("STAT cmd_touch " + cache.cmd_touch.ToString(), ref w);
                Send ("STAT get_hits " + cache.get_hits.ToString(), ref w);
                Send ("STAT get_misses " + cache.get_misses.ToString(), ref w);
                Send ("STAT delete_misses " + cache.delete_misses.ToString(), ref w);
                Send ("STAT delete_hits " + cache.delete_hits.ToString(), ref w);
                Send ("STAT incr_misses " + cache.incr_misses.ToString(), ref w);
                Send ("STAT incr_hits " + cache.incr_hits.ToString(), ref w);
                Send ("STAT decr_misses " + cache.decr_misses.ToString(), ref w);
                Send ("STAT decr_hits " + cache.decr_hits.ToString(), ref w);
                Send ("STAT cas_hits " + cache.cas_hits.ToString(), ref w);
                Send ("STAT cas_misses " + cache.cas_misses.ToString(), ref w);

                return;
            }
        }
예제 #5
0
        private static void TouchData(string parameters, ref System.IO.StreamWriter Writer, User user)
        {
            string key = null;
            int exptime = 0;
            //<command name> <key> <flags> <exptime> <bytes>
            string[] part;
            part = parameters.Split(' ');
            if (part.Length < 2)
            {
                // invalid format
                SendError(ErrorCode.MissingValues, ref Writer);
                return;
            }

            key = part[0];

            if (!int.TryParse (part[1], out exptime))
            {
                SendError(ErrorCode.MissingValues, ref Writer);
                return;
            }

            lock(MainClass.GlobalCaches)
            {
                if (!MainClass.GlobalCaches.ContainsKey(user))
                {
                    // this should never happen
                    MainClass.DebugLog("There is no cache for user " + user.username);
                    SendError(ErrorCode.InternalError, ref Writer);
                    return;
                }
                if (MainClass.GlobalCaches[user].Touch (key, exptime))
                {
                    if (!parameters.EndsWith ("noreply"))
                    {
                        Send ("TOUCHED", ref Writer);
                    }
                }
                else
                {
                    if (!parameters.EndsWith ("noreply"))
                    {
                        Send("NOT_FOUND", ref Writer);
                    }
                }
            }
        }
예제 #6
0
        /// <summary>
        /// Set the specified parameters, r and w.
        /// </summary>
        /// <param name="parameters">Parameters.</param>
        /// <param name="r">The red component.</param>
        /// <param name="w">The width.</param>
        private static int Set(string parameters, ref System.IO.StreamReader r, ref System.IO.StreamWriter w, User user)
        {
            string key = null;
            int flags = 0;
            int exptime = 0;
            int size = 0;
            //<command name> <key> <flags> <exptime> <bytes>
            string[] part = null;
            part = parameters.Split(' ');
            if (part.Length < 4)
            {
                // invalid format
                SendError (ErrorCode.MissingValues, ref w);
                return 1;
            }

            key = part[0];
            if (!int.TryParse (part[1], out flags))
            {
                SendError (ErrorCode.InvalidValues, ref w);
                return 1;
            }

            if (!int.TryParse (part[2], out exptime))
            {
                SendError (ErrorCode.InvalidValues, ref w);
                return 1;
            }

            if (!int.TryParse (part[3], out size))
            {
                SendError (ErrorCode.InvalidValues, ref w);
                return 1;
            }

            if (size < 0)
            {
                SendError (ErrorCode.InvalidValues, ref w);
                return 1;
            }

            if ((ulong)size > Configuration.InstanceMemoryLimitByteSize)
            {
                SendError (ErrorCode.OutOfMemory, ref w);
                return 3;
            }

            // everything is ok let's go
            string chunk = r.ReadLine();
            while (chunk.Length < size)
            {
                chunk += "\n" + r.ReadLine();
            }

            if (chunk.Length > size)
            {
                // too big
                SendError (ErrorCode.InvalidValues, ref w);
                return 4;
            }

            Cache.Item Item = new Cache.Item(chunk, exptime, flags);

            lock (MainClass.GlobalCaches)
            {
                if (FreeSize (MainClass.GlobalCaches[user]) < Item.getSize ())
                {
                    // we don't have enough free size let's try to free some
                    if (!MainClass.GlobalCaches[user].FreeSpace(Item.getSize ()))
                    {
                        // error
                        SendError (ErrorCode.OutOfMemory, ref w);
                        return 1;
                    }
                }
                MainClass.GlobalCaches[user].Set (key, Item);
            }

            if (!parameters.EndsWith ("noreply"))
            {
                Send ("STORED", ref w);
            }

            // unknown error
            return 0;
        }
예제 #7
0
        private static void Prepend(string pars, ref System.IO.StreamWriter w, ref System.IO.StreamReader r, User user)
        {
            if (!pars.Contains (" "))
            {
                SendError (ErrorCode.InvalidValues, ref w);
                return;
            }

            string[] part = pars.Split (' ');

            if (part.Length < 4)
            {
                SendError (ErrorCode.MissingValues, ref w);
                return;
            }

            string key = part[0];
            int flags = 0;
            int exptime = 0;
            int size = 0;
            //<command name> <key> <flags> <exptime> <bytes>

            if (!int.TryParse (part[1], out flags))
            {
                SendError (ErrorCode.InvalidValues, ref w);
                return;
            }

            if (!int.TryParse (part[2], out exptime))
            {
                SendError (ErrorCode.InvalidValues, ref w);
                return;
            }

            if (!int.TryParse (part[3], out size))
            {
                SendError (ErrorCode.InvalidValues, ref w);
                return;
            }

            if (size < 0)
            {
                SendError (ErrorCode.InvalidValues, ref w);
                return;
            }

            if ((ulong)size > Configuration.InstanceMemoryLimitByteSize)
            {
                // error
                SendError (ErrorCode.OutOfMemory, ref w);
                return;
            }

            // everything is ok let's go
            string chunk = r.ReadLine();
            while (chunk.Length < size)
            {
                chunk += "\n" + r.ReadLine();
            }

            if (chunk.Length > size)
            {
                // too big
                SendError (ErrorCode.InvalidValues, ref w);
                return;
            }

            Cache cache = MainClass.GlobalCaches[user];

            Cache.Item item = cache.Get (key, true);

            if (item == null)
            {
                Send ("NOT_FOUND", ref w);
                return;
            }

            Cache.Item replacement = new Cache.Item(item.value + chunk, item.expiry, item.flags);

            if (FreeSize (cache) < replacement.getSize())
            {
                // we don't have enough free size let's try to free some
                if (!cache.FreeSpace(replacement.getSize()))
                {
                    // error
                    SendError (ErrorCode.OutOfMemory, ref w);
                    return;
                }
            }

            cache.hardSet (key, replacement);

            if (!pars.EndsWith("noreply"))
            {
                Send ("STORED", ref w);
            }
        }
예제 #8
0
        private static void increment(string pars, ref System.IO.StreamWriter w, ref System.IO.StreamReader r, User user)
        {
            if (!pars.Contains (" "))
            {
                SendError (ErrorCode.InvalidValues, ref w);
                return;
            }

            string[] values = pars.Split (' ');

            if (values.Length < 2)
            {
                SendError (ErrorCode.MissingValues, ref w);
                return;
            }

            string key = values[0];
            int jump;

            if (!int.TryParse (values[1], out jump))
            {
                SendError(ErrorCode.InvalidValues, ref w);
                return;
            }

            Cache cache = MainClass.GlobalCaches[user];

            Cache.Item item = cache.Get (key, true);

            if (item == null)
            {
                Send ("NOT_FOUND", ref w);
                cache.incr_misses++;
                return;
            }

            int current;

            if (!int.TryParse (item.value, out current))
            {
                SendError (ErrorCode.InvalidValues, ref w);
                return;
            }

            current += jump;
            cache.incr_hits++;

            cache.hardSet (key, new Cache.Item(current.ToString (), item.expiry, item.flags));
            Send (current.ToString (), ref w);
        }
예제 #9
0
        private static void Gets(string pars, ref System.IO.StreamWriter w, ref System.IO.StreamReader r, User user)
        {
            string[] items = null;
            if (pars.Contains (" "))
            {
                items = pars.Split (' ');
            } else
            {
                items = new string[] {pars};
            }

            Cache cache = null;

            lock(MainClass.GlobalCaches)
            {
                if (!MainClass.GlobalCaches.ContainsKey(user))
                {
                    SendError (ErrorCode.InternalError, ref w);
                    return;
                }
                cache = MainClass.GlobalCaches[user];
            }
            string data = "";
            foreach (string curr in items)
            {
                Cache.Item item = cache.Get (curr);
                if (item != null)
                {
                    data += "VALUE " + curr + " " + item.flags.ToString() + " " + item.value.Length.ToString() + " " + item.cas.ToString() + "\r\n" + item.value + "\r\n";
                }
            }
            Send(data + "END", ref w);
        }
예제 #10
0
        private static void Delete(string pars, ref System.IO.StreamWriter w, ref System.IO.StreamReader r, User user)
        {
            string key = pars;
            if (key.Contains (" "))
            {
                key = key.Substring(0, key.IndexOf(" "));
            }

            Cache cache = null;

            lock(MainClass.GlobalCaches)
            {
                if (!MainClass.GlobalCaches.ContainsKey(user))
                {
                    SendError (ErrorCode.InternalError, ref w);
                    return;
                }
                cache = MainClass.GlobalCaches[user];
            }

            if (cache.Delete(key))
            {
                if (!pars.EndsWith ("noreply"))
                {
                    Send ("DELETED", ref w);
                }
                return;
            }
            if (!pars.EndsWith ("noreply"))
            {
                Send ("NOT_FOUND", ref w);
            }
        }