Пример #1
0
        // Replica metadata server append to log
        public override void AppendToLog(MetadataServer md, string command)
        {
            string[] args = command.Split(' ');
            string code = args[0];

            switch (code)
            {
                case "CREATE":
                    {
                        string clientName = args[1];
                        string filename = args[2];
                        int serversNumber = int.Parse(args[3]);
                        int readQuorum = int.Parse(args[4]);
                        int writeQuorum = int.Parse(args[5]);

                        if (!md.Files.ContainsKey(filename))
                        {
                            if (md.LiveDataServers.Count < serversNumber)
                            {
                                if (!md.PendingFiles.ContainsKey(filename))
                                {
                                    md.PendingFiles.Add(filename, serversNumber - md.LiveDataServers.Count);
                                }
                            }

                            List<string> servers = new List<string>();
                            string[] chosen = Util.SliceArray(args, 6, args.Length);

                            // Before sending the requests, a time stamp is added to the filename
                            foreach (string v in chosen)
                            {
                                servers.Add(md.LiveDataServers[v]);
                                md.ServersLoad[v]++;
                            }

                            md.ServersLoad = Util.SortServerLoad(md.ServersLoad);
                            Metadata meta = new Metadata(filename, serversNumber, readQuorum, writeQuorum, servers);
                            List<string> clientsList = new List<string>();
                            clientsList.Add(clientName);
                            md.Files.Add(filename, meta);
                            md.OpenFiles.Add(filename, clientsList);
                        }
                    }
                    break;
                case "OPEN":
                    {
                        string clientName = args[1];
                        string filename = args[2];

                        if (md.OpenFiles.ContainsKey(filename))
                        {
                            List<string> clientsList = md.OpenFiles[filename];
                            if (!clientsList.Contains(clientName))
                            {
                                md.OpenFiles[filename].Add(clientName);
                            }
                        }
                        else
                        {
                            if (md.Files.ContainsKey(filename))
                            {
                                List<string> clientsList = new List<string>();
                                clientsList.Add(clientName);
                                md.OpenFiles.Add(filename, clientsList);
                            }
                        }
                    }
                    break;
                case "CLOSE":
                    {
                        string clientName = args[1];
                        string filename = args[2];

                        if (md.Files.ContainsKey(filename))
                        {
                            if (md.OpenFiles.ContainsKey(filename))
                            {
                                List<string> clientsList = md.OpenFiles[filename];

                                if (clientsList.Contains(clientName))
                                {
                                    clientsList.Remove(clientName);

                                    if (clientsList.Count == 0)
                                    {
                                        md.OpenFiles.Remove(filename);
                                    }
                                }
                            }
                        }
                    }
                    break;
                case "DELETE":
                    {
                        string clientName = args[1];
                        string filename = args[2];
                        string[] servers = Util.SliceArray(args, 3, args.Length);

                        if (md.Files.ContainsKey(filename))
                        {
                            md.Files.Remove(filename);
                            md.OpenFiles.Remove(filename);

                            foreach (string server in servers)
                            {
                                md.ServersLoad[server]--;
                            }

                            md.ServersLoad = Util.SortServerLoad(md.ServersLoad);
                        }
                    }
                    break;
                case "REGISTER":
                    {
                        string server = args[1];
                        string name = args[2];
                        string address = args[3];

                        switch (server)
                        {
                            case "data":
                                if (!md.DataServersInfo.ContainsKey(name))
                                {
                                    md.LiveDataServers.Add(name, address);
                                    md.DataServersInfo.Add(name, null);
                                    md.ServersLoad.Add(name, 0);
                                }
                                break;
                            case "metadata":
                                if (!md.Replicas.ContainsKey(name) && name != md.Name)
                                {
                                    md.Replicas.Add(name, address);
                                }
                                break;
                            case "client":
                                if (!md.Clients.ContainsKey(name))
                                {
                                    md.Clients.Add(name, address);
                                }
                                break;
                        }
                    }
                    break;
                case "UPDATE":
                    {
                        string name = args[1];
                        string address = args[2];
                        string[] files = Util.SliceArray(args, 3, args.Length);
                        SerializableDictionary<string, int> updated = new SerializableDictionary<string, int>();
                        bool contains = false;
                        foreach (string f in files)
                        {
                            Metadata meta = md.Files[f];
                            meta.AddDataServers(address);
                            md.ServersLoad[name]++;
                            md.ServersLoad = Util.SortServerLoad(md.ServersLoad);

                            if (md.PendingFiles.ContainsKey(f))
                            {
                                int n = md.PendingFiles[f] - 1;

                                if (n > 0)
                                {
                                    updated.Add(f, n);
                                }
                                contains = true;
                            }
                        }
                        if (contains)
                        {
                            md.PendingFiles = new SerializableDictionary<string, int>(updated);
                        }
                    }
                    break;
                case "SET-PRIMARY":
                    {
                        string primary = args[1];
                        md.Primary = primary;

                        if (md.Primary == md.Name)
                        {
                            md.EnablePrimaryTimers();
                        }
                        else
                        {
                            md.EnableReplicaTimers();
                        }

                    }
                    break;
                case "TOKEN":
                    {
                        long s = long.Parse(args[1]);
                        md.Sequencer = s;
                    }
                    break;
            }

            md.Log.Append(command);
        }
Пример #2
0
 // Method used to add a new/open file to a free file register
 // Limit - 10
 private void AddToFileRegister(Metadata meta)
 {
     fileRegister[nextRegister] = meta;
     nextRegister = (nextRegister + 1) % registersLimit;
 }
Пример #3
0
        public override Metadata Create(MetadataServer md, string clientName, string filename, int serversNumber, int readQuorum, int writeQuorum)
        {
            if (md.Files.ContainsKey(filename))
            {
                throw new FileAlreadyExists("File already exists.");
            }

            if (md.LiveDataServers.Count < serversNumber)
            {
                if (!md.PendingFiles.ContainsKey(filename))
                {
                    md.PendingFiles.Add(filename, serversNumber - md.LiveDataServers.Count);
                }
            }

            List<string> servers = new List<string>();
            List<string> chosen = ChooseBestServers(serversNumber, md);

            // Before sending the requests, a time stamp is added to the filename
            string f = md.GetToken().ToString() + (char)0x7f + filename;
            foreach (string v in chosen)
            {
                List<string> arguments = new List<string>();
                arguments.Add(md.LiveDataServers[v]);
                arguments.Add(f);
                servers.Add(md.LiveDataServers[v]);
                ThreadPool.QueueUserWorkItem(CreateCallback, arguments);
                md.ServersLoad[v]++;
            }
            LoadBalanceServers(md);
            Metadata meta = new Metadata(filename, serversNumber, readQuorum, writeQuorum, servers);
            List<string> clientsList = new List<string>();
            clientsList.Add(clientName);
            md.Files.Add(filename, meta);
            md.OpenFiles.Add(filename, clientsList);
            List<object> context = new List<object>();
            context.Add(md);
            string command = string.Format("CREATE {0} {1} {2} {3} {4}", clientName, filename, serversNumber, readQuorum, writeQuorum);
            foreach (string c in chosen)
            {
                command += string.Format(" {0}", c);
            }
            context.Add(command);
            ThreadPool.QueueUserWorkItem(AppendToLog, context);

            md.Log.Append(command);

            return meta;
        }
Пример #4
0
        public void UpdateFileMetadata(string filename, Metadata metadata)
        {
            if (openFiles.ContainsKey(filename))
            {
                openFiles[filename] = metadata;

                for (int i = 0; i < registersLimit; i++)
                {
                    if (fileRegister[i] != null && fileRegister[i].Filename == filename)
                    {
                        fileRegister[i] = metadata;
                        break;
                    }
                }
            }
        }