Example #1
0
        /// WriteTo writes data to w until the buffer is drained or an error occurs.
        /// The return value n is the number of bytes written; it always fits into an
        /// int, but it is int64 to match the io.WriterTo interface. Any error
        /// encountered during the write is also returned.
        public long WriteTo(Stream w)
        {
            var n = 0L;

            _lastRead = ReadOp.opInvalid;
            if (_off < _buf.Length)
            {
                var nBytes = this.Len();

                var arr = _buf.Slice(_off).ToArray();
                w.Write(arr, 0, arr.Length);
                var m = arr.Length;
                if (m > nBytes)
                {
                    throw new Exception("bytes.Buffer.WriteTo: invalid Write count");
                }

                _off += m;
                n     = (long)m;
                // all bytes should have been written, by definition of
                // Write method in io.Writer
                if (m != nBytes)
                {
                    return(n);
                }
            }
            // Buffer is now empty; reset.
            Reset();
            return(n);
        }
Example #2
0
        public void SetupOperations(Boolean monitorOps)
        {
            if (monitorOps)
            {
                ReadOperationHandler = (b, o, c) =>
                {
                    if (m_Core.State.PC != Position && m_Core.State.BranchPC != Position)
                    {
                        Machine.Current.DeviceCPU.ResourceMonitor.CPUMemRead(Position);
                    }
                    return(base.Read(b, o, c));
                };

                WriteOperationHandler = (b, o, c) =>
                {
                    Machine.Current.DeviceCPU.ResourceMonitor.CPUMemWrite(Position);
                    base.Write(b, o, c);
                };
            }
            else
            {
                ReadOperationHandler = (b, o, c) =>
                {
                    return(base.Read(b, o, c));
                };

                WriteOperationHandler = (b, o, c) =>
                {
                    base.Write(b, o, c);
                };
            }
        }
Example #3
0
        /// ReadFrom reads data from r until EOF and appends it to the buffer, growing
        /// the buffer as needed. The return value n is the number of bytes read. Any
        /// error except io.EOF encountered during the read is also returned. If the
        /// buffer becomes too large, ReadFrom will panic with ErrTooLarge.
        public long ReadFrom(Stream r)
        //func (b *Buffer) ReadFrom(r io.Reader) (n int64, err error) {
        {
            var n = 0L;

            _lastRead = ReadOp.opInvalid;
            // If buffer is empty, reset to recover space.
            if (_off >= _buf.Length)
            {
                Reset();
            }
            for (;;)
            {
                var free = _buf.Capacity - _buf.Length;
                if (free < MinRead)
                {
                    // not enough space at end
                    var newBuf = _buf;
                    if (_off + free < MinRead)
                    {
                        // not enough space using beginning of buffer;
                        // double buffer capacity
                        newBuf = MakeSlice(2 * _buf.Capacity + MinRead);
                    }
                    newBuf.CopyFrom(_buf.Slice(_off));
                    _buf = newBuf.Slice(upper: _buf.Length - _off);
                    _off = 0;
                }

                var bytes = new byte[_buf.Capacity - _buf.Length];
                var m     = r.Read(bytes, 0, bytes.Length);
                if (m > 0)
                {
                    var slice = bytes.Slice(upper: m);
                    _buf = _buf.AppendAll(slice);

                    n += (long)m;
                }
                else
                {
                    break;
                }

                // m, e := r.Read(b.buf[len(b.buf):cap(b.buf)])
                // b.buf = b.buf[0 : len(b.buf)+m]
                // n += int64(m)
                // if e == io.EOF {
                //     break
                // }
                // if e != nil {
                //     return n, e
                // }
            }

            return(n);
            //return n, nil // err is EOF, so return nil explicitly
        }
Example #4
0
 /// WriteByte appends the byte c to the buffer, growing the buffer as needed.
 /// The returned error is always nil, but is included to match bufio.Writer's
 /// WriteByte. If the buffer becomes too large, WriteByte will panic with
 /// ErrTooLarge.
 public override void WriteByte(byte c)
 {
     _lastRead  = ReadOp.opInvalid;
     var(m, ok) = TryGrowByReslice(1);
     if (!ok)
     {
         m = GrowInternal(1);
     }
     _buf[m] = c;
 }
Example #5
0
 /// WriteString appends the contents of s to the buffer, growing the buffer as
 /// needed. The return value n is the length of s; err is always nil. If the
 /// buffer becomes too large, WriteString will panic with ErrTooLarge.
 public int WriteString(string s)
 {
     _lastRead  = ReadOp.opInvalid;
     var(m, ok) = TryGrowByReslice(s.Length);
     if (!ok)
     {
         m = GrowInternal(s.Length);
     }
     return(_buf.Slice(m).CopyFrom(Encoding.UTF8.GetBytes(s).Slice()));
 }
Example #6
0
 public void Read(ReadOp op)
 {
     if (configuration.IsInFastMode())
     {
         FastRead(op);
     }
     else
     {
         SlowRead(op);
     }
 }
Example #7
0
        /// Write appends the contents of p to the buffer, growing the buffer as
        /// needed. The return value n is the length of p; err is always nil. If the
        /// buffer becomes too large, Write will panic with ErrTooLarge.
        public int Write(slice <byte> p)
        {
            _lastRead  = ReadOp.opInvalid;
            var(m, ok) = TryGrowByReslice(p.Length);
            if (!ok)
            {
                m = GrowInternal(p.Length);
            }

            return(_buf.Slice(m).CopyFrom(p));
        }
Example #8
0
 /// UnreadRune unreads the last rune returned by ReadRune.
 /// If the most recent read or write operation on the buffer was
 /// not a successful ReadRune, UnreadRune returns an error.  (In this regard
 /// it is stricter than UnreadByte, which will unread the last byte
 /// from any read operation.)
 public void UnreadRune()
 {
     if (_lastRead <= ReadOp.opInvalid)
     {
         throw new Exception("bytes.Buffer: UnreadRune: previous operation was not a successful ReadRune");
     }
     if (_off >= (int)_lastRead)
     {
         _off -= (int)_lastRead;
     }
     _lastRead = ReadOp.opInvalid;
 }
Example #9
0
 /// UnreadByte unreads the last byte returned by the most recent successful
 /// read operation that read at least one byte. If a write has happened since
 /// the last read, if the last read returned an error, or if the read read zero
 /// bytes, UnreadByte returns an error.
 public void UnreadByte()
 {
     if (_lastRead == ReadOp.opInvalid)
     {
         throw new Exception("bytes.Buffer: UnreadByte: previous operation was not a successful read");
     }
     _lastRead = ReadOp.opInvalid;
     if (_off > 0)
     {
         _off--;
     }
 }
Example #10
0
        /// <summary>
        /// Perform standard read and update server and session state.
        /// </summary>
        /// <param name="op">The read operation</param>
        /// <param name="blob">The blob being read</param>
        /// <param name="ss">The chosen server</param>
        private void FastRead(ReadOp op)
        {
            ServerState ss = slaEngine.FindServerToRead(blobName);

            blobForRead = ClientRegistry.GetCloudBlob(ss.Name, containerName, blobName);

            watch.Start();
            op(blobForRead);
            watch.Stop();

            slaEngine.RecordObjectRead(blobForRead.Name, Timestamp(blobForRead), ss, watch.ElapsedMilliseconds);
        }
Example #11
0
        private TResult ReadLoop <TResult>(byte register, ReadOp <TResult> op) where TResult : new()
        {
            TResult result = new();

            for (int i = 0; i < MaxRetries; i++)
            {
                if (op(register, out result))
                {
                    return(result);
                }
            }

            return(result);
        }
Example #12
0
        /// Truncate discards all but the first n unread bytes from the buffer
        /// but continues to use the same allocated storage.
        /// It panics if n is negative or greater than the length of the buffer.
        public void Truncate(int n)
        {
            if (n == 0)
            {
                Reset();
                return;
            }
            _lastRead = ReadOp.opInvalid;
            if (n < 0 || n > Len())
            {
                throw new Exception("bytes.Buffer: truncation out of range");
            }

            _buf = _buf.Slice(0, _off + n);
        }
Example #13
0
        /// readSlice is like ReadBytes but returns a reference to internal buffer data.
        private (slice <byte> line, bool eof) ReadSlice(byte delim)
        {
            var line = slice <byte> .Empty;
            var eof  = false;

            var i   = _buf.Slice(_off).IndexOf(delim);
            var end = _off + i + 1;

            if (i < 0)
            {
                end = _buf.Length;
                eof = true;
            }
            line      = _buf.Slice(_off, end);
            _off      = end;
            _lastRead = ReadOp.opRead;
            return(line, eof);
        }
Example #14
0
        /// Next returns a slice containing the next n bytes from the buffer,
        /// advancing the buffer as if the bytes had been returned by Read.
        /// If there are fewer than n bytes in the buffer, Next returns the entire buffer.
        /// The slice is only valid until the next call to a read or write method.
        public slice <byte> Next(int n)
        {
            _lastRead = ReadOp.opInvalid;
            var m = Len();

            if (n > m)
            {
                n = m;
            }
            var data = _buf.Slice(_off, _off + n);

            _off += n;
            if (n > 0)
            {
                _lastRead = ReadOp.opRead;
            }
            return(data);
        }
Example #15
0
        /// WriteRune appends the UTF-8 encoding of Unicode code point r to the
        // buffer, returning its length and an error, which is always nil but is
        /// included to match bufio.Writer's WriteRune. The buffer is grown as needed;
        /// if it becomes too large, WriteRune will panic with ErrTooLarge.
        public int WriteRune(char r)
        {
            var n = 0;

            if (r < RuneSelf)
            {
                WriteByte((byte)r);
                return(1);
            }

            _lastRead  = ReadOp.opInvalid;
            var(m, ok) = TryGrowByReslice(UTFMax);
            if (!ok)
            {
                m = GrowInternal(UTFMax);
            }

            n    = _buf.Slice(m, m + UTFMax).EncodeRune(r);
            _buf = _buf.Slice(upper: m + n);
            return(n);
        }
Example #16
0
        // ReadRune reads and returns the next UTF-8-encoded
        // Unicode code point from the buffer.
        // If no bytes are available, the error returned is io.EOF.
        // If the bytes are an erroneous UTF-8 encoding, it
        // consumes one byte and returns U+FFFD, 1.
        public (char r, int size, bool eof) ReadRune()
        {
            _lastRead = ReadOp.opInvalid;
            if (_off >= _buf.Length)
            {
                // Buffer is empty, reset to recover space.
                Reset();
                return(char.MinValue, 0, eof : true);
            }
            var c = _buf[_off];

            if (c < RuneSelf)
            {
                _off++;
                _lastRead = ReadOp.opReadRune1;
                return((char)c, 1, false);
            }
            var(r, n) = _buf.Slice(_off).DecodeRune();
            _off     += n;
            _lastRead = (ReadOp)n;
            return(r, n, false);
        }
Example #17
0
        /// ReadByte reads and returns the next byte from the buffer.
        /// If no byte is available, it returns error io.EOF.
        ///
        /// NOTE: we added some additional logic here to support returning
        /// 0 when the buffer is currently empty but not signaling an EOF.
        public (byte val, bool eof) ReadByteOrEof(bool eofIfEmpty = true)
        {
            _lastRead = ReadOp.opInvalid;
            if (_off >= _buf.Length)
            {
                if (eofIfEmpty)
                {
                    // Buffer is empty, reset to recover space.
                    Reset();
                    return(0, eof : true);
                }
                else
                {
                    return(0, eof : false);
                }
            }
            var c = _buf[_off];

            _off++;
            _lastRead = ReadOp.opRead;
            return(c, false);
        }
Example #18
0
        /// Read reads the next len(p) bytes from the buffer or until the buffer
        /// is drained. The return value n is the number of bytes read. If the
        /// buffer has no data to return, err is io.EOF (unless len(p) is zero);
        /// otherwise it is nil.
        public (int val, bool eof) Read(slice <byte> p)
        {
            var n = 0;

            _lastRead = ReadOp.opInvalid;
            if (_off >= _buf.Length)
            {
                // Buffer is empty, reset to recover space.
                Reset();
                if (p.Length == 0)
                {
                    return(n, false);
                }
                return(0, eof : true);
            }
            n     = p.CopyFrom(_buf.Slice(_off));
            _off += n;
            if (n > 0)
            {
                _lastRead = ReadOp.opRead;
            }
            return(n, false);
        }
Example #19
0
        public void SetupOperations(Boolean monitorOps)
        {
            if (monitorOps)
            {
                ReadOperationHandler = (b, o, c) =>
                    {
                        if (m_Core.State.PC != Position && m_Core.State.BranchPC != Position)
                            Machine.Current.DeviceCPU.ResourceMonitor.CPUMemRead(Position);
                        return base.Read(b, o, c);
                    };

                WriteOperationHandler = (b, o, c) =>
                {
                    Machine.Current.DeviceCPU.ResourceMonitor.CPUMemWrite(Position);
                    base.Write(b, o, c);
                };
            }
            else
            {
                ReadOperationHandler = (b, o, c) =>
                {
                    return base.Read(b, o, c);
                };

                WriteOperationHandler = (b, o, c) =>
                {
                    base.Write(b, o, c);
                };
            }
        }
Example #20
0
        /// <summary>
        /// Optimization #6:
        /// Constant substitution
        ///
        /// TODO: This method has some inconsistencies when setting the offset with the new memory operations.
        ///       For some memory operations, I'm using "new {Op}(ptr + {op}.Offset)"
        ///       and for others I'm just using "new {Op}({op}.Offset)".
        ///       I'm pretty sure this inconsistency is causing some problems.
        /// </summary>
        /// <param name="operations"></param>
        private bool SubstituteConstants(ref DILOperationSet operations)
        {
            if (WereConstantsSubstituted)
            {
                return(false);
            }

            var ptr = 0;
            var arr = operations.ToArray();
            var didAnysubstitutions = false;

            for (int i = 0; i < arr.Length; i++)
            {
                var operation = arr[i];
                if (operation is AdditionMemoryOp)
                {
                    var add = (AdditionMemoryOp)operation;
                    if (add.Constant == null)
                    {
                        arr[i] = new AdditionMemoryOp(ptr + add.Offset, add.Scalar, new ConstantValue(ptr + add.Offset));
                        didAnysubstitutions = true;
                    }
                }
                else if (operation is MultiplicationMemoryOp)
                {
                    var mul = (MultiplicationMemoryOp)operation;
                    if (mul.Constant == null)
                    {
                        arr[i] = new MultiplicationMemoryOp(ptr + mul.Offset, mul.Scalar, new ConstantValue(ptr + mul.Offset), new ConstantValue(ptr));
                    }
                }
                else if (operation is AssignOp)
                {
                    var ass = arr[i] as AssignOp;
                    if (ass.Constant == null)
                    {
                        arr[i] = new AssignOp(ptr + ass.Offset, ass.Value, new ConstantValue(ptr + ass.Offset));
                        didAnysubstitutions = true;
                    }
                }
                else if (operation is PtrOp)
                {
                    arr[i] = null; // if we're using constants, then we don't need pointer movements
                    var ptrOp = (PtrOp)operation;
                    ptr += ptrOp.Delta;
                    //didAnysubstitutions = true;
                }
                else if (operation is WriteOp)
                {
                    var write = ((WriteOp)arr[i]);
                    if (write.Constant == null)
                    {
                        arr[i] = new WriteOp(write.Offset, write.Repeated, new ConstantValue(ptr));
                        didAnysubstitutions = true;
                    }
                }
                else if (operation is ReadOp)
                {
                    var read = ((ReadOp)arr[i]);
                    if (read.Constant == null)
                    {
                        arr[i] = new ReadOp(read.Offset, read.Repeated, new ConstantValue(ptr));
                        didAnysubstitutions = true;
                    }
                }
            }

            var list = arr.ToList();

            list.RemoveAll(l => l == null);

            operations = new DILOperationSet(list);

            operations.WereConstantsSubstituted = true;

            return(didAnysubstitutions);
        }
Example #21
0
        /// <summary>
        /// Perform read optimistically and then verify configuration.
        /// </summary>
        /// <param name="op">The read operation</param>
        /// <param name="blob">The blob being read</param>
        /// <param name="ss">The chosen server</param>
        /// <returns>whether the read succeeded; if not, then it should be tried again.</returns>
        private void SlowRead(ReadOp op)
        {
            // TODO: Deal with the case that we try to read from a replica that is no longer a replica and the read fails
            // In this case, the read should be retried after refreshing the configuration.
            ServerState ss = null;

            try
            {
                bool isDone = false;
                do  // until we enter fast mode or succeed at reading in slow mode with the correct configuration
                {
                    ss          = slaEngine.FindServerToRead(blobName);
                    blobForRead = ClientRegistry.GetCloudBlob(ss.Name, containerName, blobName);

                    // TODO: this should really check if the reader wants strong consistency
                    // It could be that eventual consistency is fine but the SLA Engine just happened to choose a primary server
                    // In this case, we can do a fast mode read since we don't care if the chosen server is no longer a primary
                    if (configuration.IsInFastMode() || !configuration.PrimaryServers.Contains(ss.Name))
                    {
                        // it is fine to read from the selected secondary replica
                        // or from a primary replica if we have now entered fast mode
                        FastRead(op);
                        isDone = true;
                    }
                    else
                    {
                        // read from the selected replica that we believe to be a primary replica
                        watch.Start();
                        op(blobForRead);
                        watch.Stop();

                        // then see if the configuration has changed and the selected replica is no longer primary
                        configuration.SyncWithCloud(ClientRegistry.GetConfigurationAccount());

                        // TODO: check the epoch number on the configuration to make sure that we have not missed a configuration.
                        // i.e. we need to make sure that the server from which we read did not become a secondary during our read,
                        // and then back to primary when we checked.
                        // TODO: maybe we should check that the read delivered a non-zero utility.
                        // It is possible that the configuration was so stale that a much better server could have been chosen.
                        if (configuration.PrimaryServers.Contains(ss.Name))
                        {
                            //We have contacted the primary replica, hence we are good to go.
                            slaEngine.RecordObjectRead(blobForRead.Name, Timestamp(blobForRead), ss, watch.ElapsedMilliseconds);
                            isDone = true;
                        }
                        isDone = false;  // not done
                    }
                } while (!isDone);
            }
            // TODO: decide if we need to catch any exceptions here or just let then propagate through
            catch (StorageException se)
            {
                if (StorageExceptionCode.NotFound(se))
                {
                    //blob is not found.
                    //this is fine because the replica might have removed.
                    //it simply returns, so client need to re-execute if this happens.
                    //We can also re-execute the read here, but for debugging purposes, it's simpler for the client to re-execute.
                    //Of course in real system, we need to re-execute at this level.
                    return;
                }
                // storage exceptions are passed through to the caller
                throw;
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("Object reference not set to an instance of an object"))
                {
                    return;
                }
                throw ex;
            }
        }
Example #22
0
 /// Reset resets the buffer to be empty,
 /// but it retains the underlying storage for use by future writes.
 /// Reset is the same as Truncate(0).
 public void Reset()
 {
     _buf      = _buf.Slice(upper: 0);
     _off      = 0;
     _lastRead = ReadOp.opInvalid;
 }