예제 #1
0
 protected ResourceBase(JournaledSystem journaledSystem, long id, string name, IStoreData data)
 {
     JournaledSystem = journaledSystem;
     this.id         = id;
     Name            = name;
     Data            = data;
 }
예제 #2
0
        public override void SetSize(long value)
        {
            lock (journalMap) {
                size = value;
            }

            JournaledSystem.LogResourceSizeChange(Name, size);
        }
예제 #3
0
        public override void Delete()
        {
            // Log that this resource was deleted.
            JournaledSystem.LogResourceDelete(Name);

            lock (journalMap) {
                dataExists  = false;
                dataDeleted = true;
                size        = 0;
            }
        }
예제 #4
0
        private void PersistDelete(BinaryReader reader, Dictionary <long, string> idNameMap)
        {
            // Resource delete
            long id           = reader.ReadInt64();
            var  resourceName = idNameMap[id];
            var  resource     = JournaledSystem.GetResource(resourceName);

            JournaledSystem.Context.OnDebug(String.Format("Jounral Command: Delete {0}", resourceName));

            resource.PersistDelete();
        }
예제 #5
0
        private void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (JournaledSystem != null)
                {
                    JournaledSystem.Dispose();
                }
            }

            JournaledSystem = null;
        }
예제 #6
0
            public JournalingThread(JournaledSystem system)
            {
                this.system = system;

#if PCL
                task = new Task(Execute);
#else
                thread              = new Thread(Execute);
                thread.Name         = "JournalingThread";
                thread.IsBackground = true;
#endif
            }
예제 #7
0
        private void PersistSizeChange(BinaryReader reader, Dictionary <long, string> idNameMap)
        {
            // Resource size change
            long id           = reader.ReadInt64();
            long newSize      = reader.ReadInt64();
            var  resourceName = idNameMap[id];
            var  resource     = JournaledSystem.GetResource(resourceName);

            JournaledSystem.Context.OnInformation(String.Format("Jounral Command: Set Size {0} = {1}", resourceName, newSize));

            resource.PersistSetSize(newSize);
        }
예제 #8
0
        public JournalFile(JournaledSystem journaledSystem, IFileSystem fileSystem, string path, bool readOnly)
        {
            JournaledSystem = journaledSystem;
            FileSystem      = fileSystem;
            FilePath        = path;
            ReadOnly        = readOnly;

            buffer          = new byte[36];
            resourceIdMap   = new Dictionary <string, long>();
            cur_seq_id      = 0;
            reference_count = 1;
        }
예제 #9
0
        internal LoggingBufferManager(IContext context, IFileSystem fileSystem, string journalPath, IStoreDataFactory dataFactory, int pageSize, int maxPages, bool readOnly)
        {
            Context = context;

            pageComparer = new PageComparer(this);

            JournalPath = journalPath;
            FileSystem  = fileSystem;
            PageSize    = pageSize;
            MaxPages    = maxPages;
            ReadOnly    = readOnly;

            JournaledSystem = new JournaledSystem(context, FileSystem, JournalPath, ReadOnly, true, PageSize, dataFactory);
        }
예제 #10
0
        private void PersistPageModification(BinaryReader reader, Dictionary <long, string> idNameMap)
        {
            // Page modification
            long id   = reader.ReadInt64();
            long page = reader.ReadInt64();
            int  off  = reader.ReadInt32();
            int  len  = reader.ReadInt32();

            var resourceName = idNameMap[id];
            var resource     = JournaledSystem.GetResource(resourceName);

            JournaledSystem.Context.OnDebug(String.Format(
                                                "Jounral Command: Page Change {0} page= {1} offset = {2} length = {3}", resourceName, page, off, len));

            resource.PersistPageChange(page, off, len, reader.BaseStream);
        }
예제 #11
0
        public LoggingResource(JournaledSystem journaledSystem, long id, string name, IStoreData data)
            : base(journaledSystem, id, name, data)
        {
            journalMap  = new JournalEntry[257];
            dataOpen    = false;
            dataExists  = data.Exists;
            dataDeleted = false;

            if (dataExists)
            {
                try {
                    size = data.Length;
                } catch (IOException e) {
                    throw new Exception("Error getting size of resource: " + e.Message);
                }
            }

            reallyOpen = false;
            pageBuffer = new byte[journaledSystem.PageSize];
        }
예제 #12
0
        private void PersistTag(BinaryReader reader, Dictionary <long, string> idNameMap, List <ResourceBase> resourcesUpdated)
        {
            // Resource id tag
            long          id  = reader.ReadInt64();
            int           len = reader.ReadInt32();
            StringBuilder buf = new StringBuilder(len);

            for (int i = 0; i < len; ++i)
            {
                buf.Append(reader.ReadChar());
            }

            string resourceName = buf.ToString();

            // Put this input the map
            idNameMap[id] = resourceName;

            JournaledSystem.Context.OnDebug(String.Format("Jounral Command: Tag {0} = {1}", id, resourceName));

            // Add this to the list of resources we updated.
            resourcesUpdated.Add(JournaledSystem.GetResource(resourceName));
        }
예제 #13
0
 public void Stop()
 {
     JournaledSystem.Stop();
 }
예제 #14
0
 public NonLoggingResource(JournaledSystem journaledSystem, long id, string name, IStoreData data)
     : base(journaledSystem, id, name, data)
 {
 }
예제 #15
0
 public void Start()
 {
     JournaledSystem.Start();
 }
예제 #16
0
        public override void Write(long pageNumber, byte[] buffer, int offset, int count)
        {
            lock (journalMap) {
                if (!dataOpen)
                {
                    throw new IOException("Assertion failed: Data file is not open.");
                }

                // Make this modification input the log
                var journal = JournaledSystem.LogPageModification(Name, pageNumber, buffer, offset, count);

                // This adds the modification to the END of the hash list.  This means
                // when we reconstruct the page the journals will always be input the
                // correct order - from oldest to newest.

                // The map index.
                int i     = ((int)(pageNumber & 0x0FFFFFFF) % journalMap.Length);
                var entry = journalMap[i];

                // Make sure this entry is added to the END
                if (entry == null)
                {
                    // Add at the head if no first entry
                    journalMap[i] = journal;
                    journal.Next  = null;
                }
                else
                {
                    // Otherwise search to the end
                    // The number of journal entries input the linked list
                    int journalEntryCount = 0;
                    while (entry.Next != null)
                    {
                        entry = entry.Next;
                        ++journalEntryCount;
                    }

                    // and add to the end
                    entry.Next   = journal;
                    journal.Next = null;

                    // If there are over 35 journal entries, scan and remove all entries
                    // on journals that have persisted
                    if (journalEntryCount > 35)
                    {
                        entry = journalMap[i];
                        JournalEntry prev = null;

                        while (entry != null)
                        {
                            bool deletedHash = false;

                            JournalFile file = entry.File;
                            // Note that once we have a reference the journal file can not be
                            // deleted.
                            file.Reference();

                            // If the file is closed (or deleted)
                            if (file.IsDeleted)
                            {
                                deletedHash = true;

                                // Deleted so remove the reference to the journal
                                file.Dereference();

                                // Remove the journal entry from the chain.
                                if (prev == null)
                                {
                                    journalMap[i] = entry.Next;
                                }
                                else
                                {
                                    prev.Next = entry.Next;
                                }
                            }

                            // Remove the reference
                            file.Dereference();

                            // Only move prev is we have NOT deleted a hash entry
                            if (!deletedHash)
                            {
                                prev = entry;
                            }

                            entry = entry.Next;
                        }
                    }
                }
            }
        }
예제 #17
0
 public IJournaledResource CreateResource(string resourceName)
 {
     return(JournaledSystem.CreateResource(resourceName));
 }
예제 #18
0
        public void SetCheckPoint(bool flushJournals)
        {
            // Wait until the writes have finished
            lock (writeLock) {
                while (writeLockCount > 0)
                {
                    Monitor.Wait(writeLock);
                }
                checkpointInProgress = true;
            }

            try {
                Context.OnDebug("Checkpoint requested");

                lock (pageMap) {
                    // Flush all the pages out to the log.
                    for (int i = 0; i < pageMap.Length; ++i)
                    {
                        var  page = pageMap[i];
                        Page prev = null;

                        while (page != null)
                        {
                            bool deletedHash = false;
                            lock (page) {
                                // Flush the page (will only actually flush if there are changes)
                                page.Flush();

                                // Remove this page if it is no longer in use
                                if (!page.IsUsed)
                                {
                                    deletedHash = true;
                                    if (prev == null)
                                    {
                                        pageMap[i] = page.Next;
                                    }
                                    else
                                    {
                                        prev.Next = page.Next;
                                    }
                                }
                            }

                            // Go to next page in hash chain
                            if (!deletedHash)
                            {
                                prev = page;
                            }

                            page = page.Next;
                        }
                    }
                }

                JournaledSystem.SetCheckPoint(flushJournals);
            } finally {
                // Make sure we unset the check point in progress flag and notify
                // any blockers.
                lock (writeLock) {
                    checkpointInProgress = false;
                    Monitor.PulseAll(writeLock);
                }
            }
        }