예제 #1
0
파일: WriteCache.cs 프로젝트: TheByte/sones
        /// <summary>
        /// The Writequeue add a new Position to the Lock
        /// </summary>
        /// <param name="Position">The Physical Position on the storage</param>
        public void Add(QueueEntry QueueEntry)
        {
            // this will work only if we have just 1 Stream and 1 Extent!!!
            foreach (var ObjectExtent in QueueEntry.RWQueueStreams)
            {
                var WriteQueuePositions = new Dictionary<UInt64, Byte[]>();

                lock (_Storages)
                {
                    if (_Storages[ObjectExtent.StorageUUID] == null)
                        _Storages.Add(ObjectExtent.StorageUUID, WriteQueuePositions);
                    else
                        WriteQueuePositions = (Dictionary<UInt64, Byte[]>)_Storages[ObjectExtent.StorageUUID];
                    try
                    {
                        if (WriteQueuePositions.ContainsKey(ObjectExtent.PhysicalPosition))
                        {
            //                                System.Diagnostics.Debug.WriteLine("[WriteCache]" + ObjectExtent.StorageID + "(" + WriteQueuePositions.Count + ") Overwrite " + ObjectExtent.PhysicalPosition + " Data: " + QueueEntry.Data.Length);
                            WriteQueuePositions[ObjectExtent.PhysicalPosition] = QueueEntry.Data;
                        }
                        else
                        {
            //                                System.Diagnostics.Debug.WriteLine("[WriteCache]" + ObjectExtent.StorageID + "(" + WriteQueuePositions.Count + ") Add " + ObjectExtent.PhysicalPosition + " Data: " + QueueEntry.Data.Length);
                            WriteQueuePositions.Add(ObjectExtent.PhysicalPosition, QueueEntry.Data);
                        }
                    }
                    catch
                    {
                    }
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Adds a Write request to the WriteQueue; if more than _MaxNumberOfQueueEntries are in the Queue
        /// we wait until there's less.
        /// </summary>
        /// <param name="newEntry">the WriteQueueEntry</param>
        public void Write(QueueEntry newEntry)
        {
            Boolean    WriteSucceeded  = false;
            Int16      WriteAttempt    = 0;

            // Wait, while the queue is flushing its entries
            while (BlockQueueInsertion)
                Thread.Sleep(1);

            if (ShutdownWriterThread)
                throw new QueueManagerException("[WriteQueue] Write failed, because the WriteQueueThread was shut down!");

            if (QueueIsOffline)
                throw new QueueManagerException("[WriteQueue] Write failed, because the WriteQueueThread is offline!");

            while (!WriteSucceeded && WriteAttempt <= _MaxNumberOfWriteAttempts)
            {

                QueueFull = false;

                // Lock until WriteQueue get's free to use...
                lock (WriteQueue)
                {
                    if (WriteQueue.Count >= _MaxNumberOfQueueEntries) // Falls Puffer voll
                    {
                        QueueFull = true;
                        //NStorageEngine_WriteQueueFull.Arguments args = new NStorageEngine_WriteQueueFull.Arguments();
                        //args.NumberOfQueueEntries = NumberOfQueueEntries;

                        //NotificationDispatcher.SendNotification(typeof(NStorageEngine_WriteQueueFull), args);
                    }
                }

                if (QueueFull)
                    lock (WriteQueueHasFreeSpace)
                    {
                        // Wartet bis wieder Platz im Puffer vorhanden ist
                        Monitor.Wait(WriteQueueHasFreeSpace);
                        QueueFull = false;
                    }

                lock (WriteQueue)
                {

                    WriteAttempt++;

                    if (WriteQueue.Count < _MaxNumberOfQueueEntries)
                    {

                        WriteQueue.Add(newEntry);

                        // CORRECTION: Add a new Entry to Writequeue - Prevent Readqueue from reading not yet written positions
                        /*
                        foreach (var _ObjectExtent in newEntry.RWQueueStreams)
                            _WriteQueueLock.AddLock(_ObjectExtent.PhysicalPosition);
                        */

            //                        Debug.WriteLine("[WriteQueue] Adding new entry!");

                        //Debug.WriteLine("[WriteQueueThread] Added to the queue!");

                        // Wake the WriteQueueThread if it was fallen asleep
                        WriteSucceeded  = true;

                        if (WriteQueueThreadSleeping)
                            lock (WriteQueueHasNewElements)
                            {
                                // Signalisiert, dass wieder ein Element vorhanden ist
                                Monitor.PulseAll(WriteQueueHasNewElements);
                            }

                    }

                }

            }

            // ...fail afterwards!
            // This should actually never happen!!!
            if (!WriteSucceeded)
                throw new QueueManagerCouldNotWriteQueueException("[WriteQueue] Could not write to the queue!");
        }
예제 #3
0
        /// <summary>
        /// Reads a pile of data from the filesystem
        /// </summary>
        /// <param name="ReadEntry">a QueueEntry </param>
        /// <returns></returns>
        public byte[] Read(QueueEntry ReadEntry)
        {
            // check size
            if (ReadEntry.DataLength > Int32.MaxValue)
                throw new QueueManagerException("Cannot read QueueEntry - it's too big.");

            byte[] Output = new byte[ReadEntry.DataLength];

            // TODO: actually make use of the read queue...

            if (!GraphFSFileStream.CanRead)
                throw new QueueManagerException("Cannot read. Maybe nothing is mounted.");

            // CORRECTION: Check if the current StartPosition is still in the WriteQueue - Prevent Readqueue from reading not yet written positions
            /*
            while (_WriteQueueLock.HasLock(ReadEntry.RWQueueStreams[0].PhysicalPosition))
            {
                Debug.WriteLine("[ReadQueue] has lock at Position " + ReadEntry.RWQueueStreams[0].PhysicalPosition);
                Thread.Sleep(1); // or read next in queue
            }
            */
            lock (GraphFSFileStream)
            {
                GraphFSFileStream.Seek( (long) ReadEntry.RWQueueStreams[0].PhysicalPosition, 0);
                Int32 HowMany = GraphFSFileStream.Read(Output, 0, (Int32)ReadEntry.RWQueueStreams[0].Length);

                if (_BytesRead + (UInt64) HowMany < 0)
                    _BytesRead = 0;

                _BytesRead += (UInt64) HowMany;
            }
            //Debug.WriteLine("[ReadQueue] Reading " + Output.Length + " bytes from position " + ReadEntry.Streams[0].Extents[0].PhysicalPosition);
            //Debug.WriteLine("   \t_WriteQueuePositions" + ((List<UInt64>)UnitTestHelper.GetPrivateField("_WriteQueuePositions", _WriteQueueLock)).Count);

            return Output;
        }
예제 #4
0
        /// <summary>
        /// This method writes directly a QueueEntry as soon as possible on disc.
        /// It does this by putting the QueueEntry infront of all other QueueEntries
        /// within the queue.
        /// In most cases this is not what you want: USE WITH CARE!
        /// </summary>
        /// <param name="newEntry">the QueueEntry that needs to be written as soon as possible</param>
        public void DirectWrite(QueueEntry newEntry)
        {
            // Wait, while the queue is flushing its entries
            while (BlockQueueInsertion)
                Thread.Sleep(1);

            if (ShutdownWriterThread)
                throw new QueueManagerException("[WriteQueue] Write failed, because the WriteQueueThread was shut down!");

            if (QueueIsOffline)
                throw new QueueManagerException("[WriteQueue] Write failed, because the WriteQueueThread is offline!");

            newEntry.FlushAfterWrite = true;

            lock (WriteQueue)
            {
                WriteQueue.Insert(0, newEntry);
            }
        }