Esempio n. 1
0
        public User FirstUser(Predicate <User> p)
        {
            if (p == null)
            {
                return(null);           // Done to conveniently handle system insertions
            }
            // Check if user is scheduled for removal
            foreach (var entry in toRemove)
            {
                if (p(entry))
                {
                    return(null);
                }
            }

            // Check loaded users
            foreach (var entry in loadedUsers)
            {
                if (p(entry))
                {
                    return(entry);
                }
            }

            // Check modified users
            foreach (var entry in changeList)
            {
                if (p(entry))
                {
                    if (!loadedUsers.Contains(entry))
                    {
                        loadedUsers.Add(entry);
                    }
                    return(entry);
                }
            }

            // Read from database
            using (var reader = XmlReader.Create(DatabaseName))
            {
                if (!Traverse(reader, MasterEntry))
                {
                    return(null);
                }
                while ((reader.Name.Equals("User") && reader.NodeType != XmlNodeType.EndElement) || (reader.Read() && reader.NodeType != XmlNodeType.EndElement))
                {
                    if (reader.Name.Equals("User"))
                    {
                        User n = FromEncoded(User.Parse(ReadEntry(reader), this));
                        if (n != null && p(n))
                        {
                            if (!loadedUsers.Contains(n))
                            {
                                loadedUsers.Add(n);
                            }
                            return(n);
                        }
                    }
                }
            }
            return(null);
        }
Esempio n. 2
0
        // Permissive (cache-dependent) flush
        private void Flush(bool optional)
        {
            if (optional && (changeList.Count < 30 && toRemove.Count < 30))
            {
                return;                                                            // No need to flush
            }
            string temp = GenerateTempFileName("tmp_", ".xml");

            using (var writer = XmlWriter.Create(temp))
            {
                using (var reader = XmlReader.Create(DatabaseName))
                {
                    int  masterDepth = 0;
                    bool trigger = false, wn = false, recent = false, justTriggered = false;
                    while (wn || reader.Read() || (reader.NodeType == XmlNodeType.None && justTriggered))
                    {
                        justTriggered = false;
                        wn            = false;
                        if (trigger)
                        {
                            foreach (var user in changeList)
                            {
                                WriteUser(writer, user);
                            }

                            bool wroteNode = false;
                            while ((wroteNode || reader.Name.Equals("User") || reader.Read()) && reader.NodeType != XmlNodeType.EndElement && reader.NodeType != XmlNodeType.None)
                            {
                                wroteNode = false;
                                if (reader.Name.Equals("User"))
                                {
                                    User u = FromEncoded(User.Parse(ReadEntry(reader), this));
                                    if (u != null)
                                    {
                                        bool shouldWrite = true;
                                        foreach (var toChange in changeList)
                                        {
                                            if (toChange.Name.Equals(u.Name))
                                            {
                                                shouldWrite = false;
                                                break;
                                            }
                                        }
                                        if (shouldWrite)
                                        {
                                            foreach (var remove in toRemove)
                                            {
                                                if (remove.Name.Equals(u.Name))
                                                {
                                                    shouldWrite = false;
                                                    break;
                                                }
                                            }
                                        }
                                        if (shouldWrite)
                                        {
                                            WriteUser(writer, u);
                                        }
                                    }
                                }
                                else
                                {
                                    wroteNode = true;
                                    writer.WriteNode(reader, true);
                                }
                            }
                            trigger = false;
                            recent  = true;
                            writer.WriteEndElement();
                            toRemove.Clear();
                            changeList.Clear();
                        }
                        if (masterDepth != MasterEntry.Length && reader.Name.Equals(MasterEntry[masterDepth]))
                        {
                            trigger       = reader.NodeType == XmlNodeType.Element && ++masterDepth == MasterEntry.Length;
                            justTriggered = true;
                            reader.MoveToContent();
                            writer.WriteStartElement(MasterEntry[masterDepth - 1]);
                        }
                        else if (masterDepth == MasterEntry.Length && recent)
                        {
                            if (masterDepth != 1)
                            {
                                writer.WriteEndElement();
                            }
                            recent = false;
                        }
                        else
                        {
                            wn = true;
                            writer.WriteNode(reader, true);
                        }
                    }
                }
                writer.Flush();
            }

            File.Delete(DatabaseName);
            File.Move(temp, DatabaseName);
        }