예제 #1
0
        public bool Enqueue(int level, string msg)
        {
            var c    = Encoding.UTF8.GetBytes(msg);
            var data = new byte[c.Length + HeaderSize];
            var s    = new MemoryStream(data);

            using (var sw = new BinaryWriter(s))
            {
                sw.Write(level);              // 4
                sw.Write(DateTime.Now.Ticks); // 8
                sw.Write(c.Length);           // 4
                sw.Write(c);
            }

            using (var stream = MMF.CreateViewStream())
            {
                stream.Position = Front;
                if (IsFull)
                {
                    // No space
                    Log("No space for writing data");
                    return(false);
                }
                else
                {
                    if (Front + data.Length < stream.Length)
                    {
                        // Enough space to go
                        stream.Write(data, 0, data.Length);
                        Front = stream.Position;
                        Log("Enough space, enqueue data");
                    }
                    else
                    {
                        // No enough space, break into two parts
                        var firstLen  = (int)(stream.Length - Front);
                        var secondLen = data.Length - firstLen;
                        stream.Write(data, 0, firstLen);
                        stream.Position = ReservedSize; // reset to begin
                        stream.Write(data, firstLen - 1, secondLen);
                        Front = stream.Position;
                        Log("Split data and enqueue");
                    }

                    IsEmpty = false;
                }

                // 1. Front is catching up Rear in next cycle
                // 2. Front is near the end of the stream, and remaining data in the head is not enough
                if ((Rear > Front && Rear - Front < HeaderSize) || (stream.Length - Front - 1 + (Rear - ReservedSize)) < HeaderSize)
                {
                    IsFull = true;
                }

                Log("Front:{0}, Rear:{1}", Front, Rear);
                return(true);
            }
        }
예제 #2
0
        public SharedMessage Dequeue()
        {
            using (var stream = MMF.CreateViewStream())
            {
                if (IsEmpty)
                {
                    Log("No Data");
                    return(null);
                }
                else
                {
                    using (var sr = new BinaryReader(stream))
                    {
                        stream.Position = Rear;
                        var header = new byte[HeaderSize];
                        if (stream.Length - Rear >= HeaderSize)
                        {
                            header = sr.ReadBytes(HeaderSize);
                        }
                        else
                        {
                            var firstLen  = (int)(stream.Length - stream.Position);
                            var secondLen = HeaderSize - firstLen;
                            var header1   = sr.ReadBytes(firstLen);
                            stream.Position = ReservedSize;
                            var header2 = sr.ReadBytes(secondLen);
                            Array.Copy(header1, header, firstLen);
                            Array.Copy(header2, 0, header, firstLen - 1, secondLen);
                        }
                        var level = BitConverter.ToInt32(header, 0);
                        var time  = new DateTime(BitConverter.ToInt64(header, 4));
                        var len   = BitConverter.ToInt32(header, 12);

                        var msg = new byte[len];
                        if (stream.Position + len <= stream.Length)
                        {
                            msg = sr.ReadBytes(len);
                        }
                        else
                        {
                            var firstLen  = (int)(stream.Length - stream.Position);
                            var secondLen = len - firstLen;
                            var msg1      = sr.ReadBytes(firstLen);
                            stream.Position = ReservedSize;
                            var msg2 = sr.ReadBytes(secondLen);
                            Array.Copy(msg1, msg, firstLen);
                            Array.Copy(msg2, 0, msg, firstLen - 1, secondLen);
                        }

                        Rear   = stream.Position;
                        IsFull = false;

                        // 1. Rear is catching up Front
                        // 2. Rear is near the end of the stream, the remaining data is not enough
                        if (Front - Rear < HeaderSize || (stream.Length - Rear - 1 + (Front - ReservedSize)) < HeaderSize)
                        {
                            IsEmpty = true;
                        }

                        Log("Front:{0}, Rear:{1}", Front, Rear);
                        var message = Encoding.UTF8.GetString(msg);
                        Log("Level:{0}, Time:{1}, Message:{2}", level, time, message);
                        return(new SharedMessage()
                        {
                            Level = level,
                            Timestamp = time,
                            Message = message
                        });
                    }
                }
            }
        }