Write_ByOffset() public method

public Write_ByOffset ( int offset, byte &data ) : void
offset int
data byte
return void
Example #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="offset"></param>
        /// <param name="data"></param>
        public void Table_WriteByOffset(long offset, byte[] data)
        {
            /* Emulation of the direct save without random cache */
            //lock (lock_fs)
            //{
            //    FlushSequentialBuffer();
            //    _fsData.Position = offset;
            //    _fsData.Write(data, 0, data.Length);
            //}

            //Console.WriteLine("yeah");
            //return;
            /******************************************************/


            //DB RULE1. We cant update and go out of the end of file
            //!! ALL throw new Exception must be taken away after testS
            //!! This is a cutted implementation for DBreeze we dont take care buffer elements overlapping (start+len U some elements -> should be not possible)
            //overwriting partly file and partly sequential buffer is not allowed

            if (data == null || data.Length == 0)
            {
                throw new Exception("FSR.WriteByOffset: data == null || data.Length == 0");
            }

            lock (lock_fs)
            {
                if (offset >= _fsData.Length)
                {
                    //Overwriting sequential buffer
                    _seqBuf.Write_ByOffset(Convert.ToInt32(offset - _fsData.Length), data);
                    return;
                }

                if (offset < _fsData.Length && offset + data.Length > _fsData.Length)
                {
                    throw new Exception("FSR.WriteByOffset: offset < _fsData.Length && offset + data.Length > _fsData.Length");
                }

                if (offset + data.Length > (_fsData.Length + _seqBuf.EOF))
                {
                    //DB RULE1. We cant update and go out of the end of file. Only if we write into empty file root in the beginning
                    throw new Exception("FSR.WriteByOffset: offset + data.Length > (_fsData.Length + seqEOF)");
                }

                byte[] inBuf = null;
                if (_randBuf.TryGetValue(offset, out inBuf))
                {
                    if (inBuf.Length != data.Length)
                    {
                        //OLD solution
                        //it means we overwrite second time the same position with different length of data - what is not allowed
                        //throw new Exception("FSR.WriteByOffset: inBuf.Length != data.Length");

                        //Solution from 20140425
                        //we just overwrite offset value with the new data
                    }

                    //setting new value for such offset
                    _randBuf[offset] = data;
                }
                else
                {
                    //We put data to the buffer first and flush it if buffer > allowed space. We dont take care if data is bigger then buffer.
                    //In any case first we put it to the buffer
                    _randBuf.Add(offset, data);
                    usedBufferSize += data.Length;
                }

                //if we are able to store data into buffer lets do it
                if (usedBufferSize >= maxRandomBufferSize || _randBuf.Count() > maxRandomElementsCount)
                {
                    FlushRandomBuffer();
                }
            }
        }
Example #2
0
        /// <summary>
        /// Is called only from lock_fs and must be finished by calling NET_Flush
        /// </summary>
        /// <param name="commit"></param>
        void FlushRandomBuffer()
        {
            if (_randBuf.Count() == 0)
            {
                return;
            }

            //First we write all data into rollback file and helper, calling flush on rollback
            //then updating data of data file but dont call update
            //clearing random buffer

            //Creating rollback header
            byte[] offset = null;
            byte[] btRoll = null;

            bool flushRollback = false;

            //first loop for saving rollback data
            foreach (var de in _randBuf.OrderBy(r => r.Key))      //sorting can mean nothing here, only takes extra time
            {
                offset = ((ulong)de.Key).To_8_bytes_array_BigEndian().Substring(8 - DefaultPointerLen, DefaultPointerLen);

                if (_rollbackCache.ContainsKey(de.Key))
                {
                    continue;
                }

                //Reading from dataFile values which must be rolled back
                btRoll = new byte[de.Value.Length];

                _fsData.Write_ByOffset((int)de.Key, ref btRoll);

                //Forming protocol for rollback
                btRoll = new byte[] { 1 }
                .ConcatMany(
                    offset,
                    ((uint)btRoll.Length).To_4_bytes_array_BigEndian(),
                    btRoll
                    );

                //Writing rollback
                _fsRollback.Write_ByOffset((int)eofRollback, ref btRoll);

                _rollbackCache.Add(de.Key, new r {
                    o = eofRollback + 1 + offset.Length + 4, l = de.Value.Length
                });                                                                                                  //10 is size of protocol data

                //increasing eof rollback file
                eofRollback += btRoll.Length;

                flushRollback = true;
            }

            if (flushRollback)
            {
                //Writing into helper
                btRoll = eofRollback.To_8_bytes_array_BigEndian();
                _fsRollbackHelper.Write_ByOffset(0, ref btRoll);

                //Flushing rollback and rollback helper
            }


            //second loop for saving data
            foreach (var de in _randBuf.OrderBy(r => r.Key))      //sorting can mean nothing here, only takes extra time
            {
                btRoll = de.Value;
                _fsData.Write_ByOffset((int)de.Key, ref btRoll);
            }

            //No flush of data file, it will be done on Flush()

            _randBuf.Clear();
            usedBufferSize = 0;
        }