Read() public method

If length = 0 returns new byte[0]
public Read ( int offset, int length ) : byte[]
offset int
length int
return byte[]
Example #1
0
        /// <summary>
        /// Standard and transactional rollback
        /// </summary>
        public void Rollback()
        {
            try
            {
                lock (lock_fs)
                {
                    //Clearing random buffer
                    if (_randBuf.Count() != 0)
                    {
                        usedBufferSize = 0;
                        _randBuf.Clear();
                    }

                    //Restoring Rollback records
                    byte[] btWork = null;

                    if (_rollbackCache.Count() > 0)
                    {
                        foreach (var rb in _rollbackCache)
                        {
                            btWork = new byte[rb.Value.l];

                            btWork = _fsRollback.Read((int)rb.Value.o, btWork.Length);

                            //_fsRollback.Position = rb.Value.o;
                            //_fsRollback.Read(btWork, 0, btWork.Length);

                            _fsData.Write_ByOffset((int)rb.Key, btWork);
                            //_fsData.Position = rb.Key;
                            //_fsData.Write(btWork, 0, btWork.Length);
                        }

                        //NET_Flush(_fsData);

                        //Restoring rhp
                        eofRollback = 0;
                        btWork      = eofRollback.To_8_bytes_array_BigEndian();
                        _fsRollbackHelper.Write_ByOffset(0, btWork);
                        //_fsRollbackHelper.Position = 0;
                        //_fsRollbackHelper.Write(eofRollback.To_8_bytes_array_BigEndian(), 0, 8);

                        //NET_Flush(_fsRollbackHelper);

                        //Clearing rollbackCache
                        _rollbackCache.Clear();
                    }

                    //we dont move eofData, space can be re-used up to next restart (may be root can have this info in next protocols)
                    //eofData = this._fsData.Length;
                }
            }
            catch (Exception ex)
            {
                IsOperable = false;
                throw DBreezeException.Throw(DBreezeException.eDBreezeExceptions.RESTORE_ROLLBACK_DATA_FAILED, this._fileName, ex);
            }
        }
Example #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="readActual">if actual overwritten data must be used</param>
        /// <param name="offset"></param>
        /// <returns></returns>
        public byte[] Table_Read(bool useCache, long offset, int count)
        {
            byte[] res = null;

            //if (count == 0)     //!!! also not necessary, but can be while testing period under exception
            //    return null;

            lock (lock_fs)
            {
                if (!useCache)
                {
                    //We read exactly what is already saved, without rollback.
                    //all data must be either in file or in buffer
                    //we must form resulting byte[]

                    //Buffer
                    //Finding first element which is smaller or equal then offset
                    List <long> bufKeys = new List <long>();

                    if (_randBuf.Count() > 0)
                    {
                        var qkvp = _randBuf.OrderByDescending(r => r.Key).Where(r => r.Key < offset).Take(1).Where(r => (r.Key + r.Value.Length - 1) >= offset);


                        if (qkvp.Count() > 0)
                        {
                            bufKeys.Add(qkvp.FirstOrDefault().Key);
                        }

                        foreach (var kvp in _randBuf.OrderBy(r => r.Key).Where(r => r.Key >= offset && r.Key < (offset + count)))
                        {
                            bufKeys.Add(kvp.Key);
                        }
                    }

                    //reading full byte[] from original file and putting on top keys
                    //We use full length of the file
                    if (offset + count > _fsData.EOF)
                    {
                        res = new byte[_fsData.EOF - offset];
                    }
                    else
                    {
                        res = new byte[count];
                    }

                    res = _fsData.Read((int)offset, res.Length);

                    byte[] btWork = null;
                    //putting on top
                    foreach (var bk in bufKeys)
                    {
                        btWork = _randBuf[bk];

                        bool cut   = false;
                        int  start = 0;
                        int  stop  = btWork.Length;

                        if (bk < offset)
                        {
                            cut   = true;
                            start = Convert.ToInt32(offset - bk);
                        }

                        if ((offset + count) < (bk + btWork.Length))
                        {
                            cut  = true;
                            stop = Convert.ToInt32(offset + count - bk);
                        }

                        if (cut)
                        {
                            byte[] tmp = new byte[stop - start];
                            Buffer.BlockCopy(btWork, start, tmp, 0, tmp.Length);
                            btWork = tmp;
                        }

                        Buffer.BlockCopy(btWork, 0, res, (start > 0) ? 0 : Convert.ToInt32(bk - offset), btWork.Length);
                    }
                }
                else
                {
                    //we must use rollback file.
                    //We can read only up to commited file lengh eofData

                    List <long> bufKeys = new List <long>();

                    if (_rollbackCache.Count() > 0)
                    {
                        var qkvp = _rollbackCache.OrderByDescending(r => r.Key).Where(r => r.Key < offset).Take(1).Where(r => (r.Key + r.Value.l - 1) >= offset);


                        if (qkvp.Count() > 0)
                        {
                            bufKeys.Add(qkvp.FirstOrDefault().Key);
                        }

                        foreach (var kvp in _rollbackCache.OrderBy(r => r.Key).Where(r => r.Key >= offset && r.Key < (offset + count)))
                        {
                            bufKeys.Add(kvp.Key);
                        }
                    }

                    //reading full byte[] from original file and putting on top keys

                    /*
                     * Transaction with minimum 2 tables. T2 is inserted, reference to T2 KVP is taken, then this reference is saved into T1.
                     * Commit().
                     * Commit calls TransactionalCommit for every table sequentially. First it meets table T1, then T2.
                     * In both tables TransactionalCommit procedures are successfull.
                     * then Commit procedure for each table calls TransactionalCommitIsFinished (this proc will clear rollback refs and moves eofData for every table).
                     * First encounters T1 and only then T2.
                     * ....Somewhere here (between calling T1 and T2 TransactionalCommitIsFinished) starts a parallel thread.
                     * After T1 TransactionalCommitIsFinished our parallel thread P1 reads data from T1,
                     * and gets SelectDirect reference to T2 KVP. Then tries to read from not yet TransactionalCommitIsFinished T2.
                     * and for T2 happens: eofData < offset
                     *
                     * To avoid such specific case we use for calculation this._fsData.Length instead of eofData in case if (eofData < offset && TransactionalCommitIsStarted)
                     * 19.07.2013 10:25
                     */

                    //WAS
                    //if (offset + count > eofData)
                    //    res = new byte[eofData - offset];
                    //else
                    //    res = new byte[count];
                    //////

                    //NOW
                    if (offset + count > eofData)
                    {
                        if (eofData < offset && TransactionalCommitIsStarted)   //NOT FINISHED multi-table COMMIT. SelectDirect case
                        {
                            //Probably not finished transaction and SelectDirect case. We return value,
                            //because at this momont all transaction table have successfully gone through TransactionalCommit() procedure.

                            if (offset + count > this._fsData.EOF)
                            {
                                res = new byte[this._fsData.EOF - offset];
                            }
                            else
                            {
                                res = new byte[count];
                            }
                        }
                        else
                        {
                            res = new byte[eofData - offset];
                        }
                    }
                    else
                    {
                        res = new byte[count];
                    }
                    ///////


                    res = _fsData.Read((int)offset, res.Length);


                    byte[] btWork = null;
                    r      rb     = null;
                    //putting on top
                    foreach (var bk in bufKeys)
                    {
                        rb = _rollbackCache[bk];
                        //reading from rollback
                        btWork = new byte[rb.l];

                        btWork = _fsData.Read((int)rb.o, btWork.Length);

                        bool cut   = false;
                        int  start = 0;
                        int  stop  = btWork.Length;

                        if (bk < offset)
                        {
                            cut   = true;
                            start = Convert.ToInt32(offset - bk);
                        }

                        if ((offset + count) < (bk + btWork.Length))
                        {
                            cut  = true;
                            stop = Convert.ToInt32(offset + count - bk);
                        }

                        if (cut)
                        {
                            byte[] tmp = new byte[stop - start];
                            Buffer.BlockCopy(btWork, start, tmp, 0, tmp.Length);
                            btWork = tmp;
                        }

                        Buffer.BlockCopy(btWork, 0, res, (start > 0) ? 0 : Convert.ToInt32(bk - offset), btWork.Length);
                    }
                }
            }


            return(res);
        }