// Проверка таблицы public bool CheckTable(Log log) { log.Append("---------------------------------------\r\nBegin check data of table: ", Key, ", count: ", Count, "\r\n"); var flag = false; if (CurrentVersion.Mode == PageFileIOMode.Standart) { log.Append("Check not supported."); return(flag); } var count = Count; var map = File.GetDeletedMap(); var rdr = File.GetReader(); var err = 0; var crc32 = new CRC32(); for (int i = 1; i < count; ++i) { if (map.Contains(i)) { continue; } long time; int crc; var b = rdr.ReadWithCRC(i, out time, out crc); crc32.Update(b, 0, b.Length); crc32.Update(time); if (crc32.Value != crc) { flag = true; err++; if (err < 10) { log.Append("Crc check fail at: " + i + "\r\n"); } } crc32.Reset(); if (i > 0 && i % 100000 == 0) { log.Append("Progresss : ", i, "\r\n"); } } File.ReleaseReader(rdr); return(flag); }
public void WriteAndResetCRC() { bw.Write(crc32.Value); crc32.Reset(); }
// Восстановление таблицы из бекапа internal bool RestoreTable(ITable itm, ArrayStorage storage, BinaryReaderCRC32 sm, FileStream sd, Log log) { if (sm.Stream.Position != Offset) { sm.Stream.Position = Offset; } //Debug.WriteLine("Restore " + itm.Key); itm.File.SetCount(Count); var flag = true; var wtr = itm.File.CreateStream(); var sd_br = new BinaryReader(sd); var crc = new CRC32(); var crcerr = 0; var hasCRC = (itm.CurrentVersion.Mode & PageFileIOMode.CRC32) == PageFileIOMode.CRC32; var size = RecordSize; if (!hasCRC) { size += size_crc; } var buf = new byte[size]; var list = new List <byte[]>(); try { if (itm.Key == "Users") { int bp = 0; } var sw = Stopwatch.StartNew(); //if (itm.Key == "Regions") //{ // int bp = 0; //} // Если есть массивыв переменной длинны if (HasStorage) { // i + 1 - это код for (var i = 0; i < Count; ++i) { var offset = sm.ReadInt64(); //Debug.WriteLine("Restore " + itm.Key + ", code: " + (i + 1) + ", offset:" + offset); if (i + 1 == 1350685) { var bp = 0; } if (sd.Position != offset) { sd.Position = offset; } var time = sd_br.ReadInt64(); // Проверяем на удаление if (time < 0) { itm.File.deleted.Push(i + 1); continue; } else { // обновляем crc времени crc.Update(time); } list.Clear(); // Считаем CRC for (var j = 0; j < Fields.Count; ++j) { var fld = Fields[j]; if (fld.IsStorage) { //Debug.WriteLine("Restore " + itm.Key + ", code: " + (i + 1) + ", field: " + fld.Name + " pos: " + sd.Position); var len = sd_br.ReadInt32(); var tmp = new byte[len]; sd.Read(tmp, 0, len); crc.Update(len); crc.Update(tmp, 0, tmp.Length); list.Add(tmp); } else { var off = fld.Offset; switch (fld.Size) { case 1: { var val = sd_br.ReadByte(); buf[off] = val; crc.Update(val); break; } case 2: { var val = sd_br.ReadChar(); fixed(byte *ptr = &buf[off]) { var tmp = (char *)ptr; *tmp = val; } crc.Update(val); break; } case 4: { var val = sd_br.ReadUInt32(); fixed(byte *ptr = &buf[off]) { var tmp = (uint *)ptr; *tmp = val; } crc.Update(val); break; } case 8: { var val = sd_br.ReadUInt64(); fixed(byte *ptr = &buf[off]) { var tmp = (ulong *)ptr; *tmp = val; } crc.Update(val); break; } case 16: { var val = sd_br.ReadDecimal(); fixed(byte *ptr = &buf[off]) { var tmp = (decimal *)ptr; *tmp = val; } crc.Update(val); break; } } } } // Проверяем crc массивов var crc2 = sd_br.ReadInt32(); if (crc.Value != crc2) { flag = false; crc.Reset(); crcerr++; if (crcerr < 10) { log.Append("Record code: " + (i + 1) + " error crc32 array check.\r\n"); } continue; } // Записываем массивы var n = 0; for (var j = 0; j < Fields.Count; ++j) { var fld = Fields[j]; if (fld.IsStorage) { var tmp = list[n++]; var key = storage.WriteBuffer(0, tmp); fixed(byte *b = &buf[fld.Offset]) { var ptr = (long *)b; *ptr = key; } //if (itm.Key == "Users" && i == 0 && fld.Name == "Awatar") //{ // DataBase.TestKey = key; // DataBase.TestString = System.Text.Encoding.Unicode.GetString(tmp); //} } } var wtr_offset = PageFile.HeaderSize + (i + 1) * itm.CurrentVersion.RecordSize; //Debug.WriteLine("Write pos: " + wtr_offset); // Устанавливаем позицию if (wtr.Position != wtr_offset) { wtr.Position = wtr_offset; } // Записываем запись if (hasCRC) { crc.Reset(); fixed(byte *ptr = &buf[size - size_time_crc]) { var tmp = (long *)ptr; *tmp = time; } crc.Update(buf, 0, size - size_crc); fixed(byte *ptr = &buf[size - size_crc]) { var tmp = (int *)ptr; *tmp = crc.Value; } // Данные, время и CRC wtr.Write(buf, 0, size); } else { fixed(byte *ptr = &buf[size - size_time_crc]) { var tmp = (long *)ptr; *tmp = time; } // Данные и время wtr.Write(buf, size_time, size - size_crc); } crc.Reset(); //if (i > 0 && i%100000 == 0) //{ // log.Append("Progresss : ", i, "\r\n"); //} if (sw.ElapsedMilliseconds >= 1000) { log.Append("Progresss : ", i, ", ", (i * 100) / Count, "% \r\n"); sw.Restart(); } } } else { for (var i = 0; i < Count; ++i) { if (i + 1 == 1350685) { var bp = 0; } var offset = sm.ReadInt64(); //Debug.WriteLine("Restore " + itm.Key + ", code: " + (i + 1) + ", offset:" + offset); if (sd.Position != offset) { sd.Position = offset; } // Читаем запись sd.Read(buf, 0, size); // Проверяем на удаление fixed(byte *b = &buf[0]) { var ptr = (long *)b; if (*ptr < 0) { itm.File.deleted.Push(i + 1); continue; } else { // обновляем crc времени crc.Update(*ptr); } } // обновляем crc данных crc.Update(buf, size_time, size - size_time_crc); // Проверяем crc данных fixed(byte *b = &buf[size - size_crc]) { var ptr = (int *)b; if (crc.Value != *ptr) { flag = false; crc.Reset(); crcerr++; if (crcerr < 10) { log.Append("Record code: " + (i + 1) + " error crc32 data check.\r\n"); } continue; } } var wtr_offset = PageFile.HeaderSize + (i + 1) * itm.CurrentVersion.RecordSize; // Устанавливаем позицию записи if (wtr.Position != wtr_offset) { wtr.Position = wtr_offset; } // Записываем запись if (hasCRC) { // Пересчитываем crc под формат бд crc.Reset(); crc.Update(buf, size_time, size - size_time_crc); crc.Update(buf, 0, size_time); fixed(byte *ptr = &buf[size - size_crc]) { var tmp = (int *)ptr; *tmp = crc.Value; } // Данные wtr.Write(buf, size_time, size - size_time_crc); // Время wtr.Write(buf, 0, size_time); // CRC wtr.Write(buf, size - size_crc, size_crc); } else { // Данные wtr.Write(buf, size_time, size - size_time_crc); // Время wtr.Write(buf, 0, size_time); } crc.Reset(); //if (i > 0 && i%100000 == 0) //{ // log.Append("Progresss : ", i, "\r\n"); //} if (sw.ElapsedMilliseconds >= 1000) { log.Append("Progresss : ", i, ", ", (i * 100) / Count, "% \r\n"); sw.Restart(); } } } } catch (Exception ex) { log.Append("Exception: "); log.Append(ex.Message); } finally { wtr.Flush(); wtr.Close(); } return(flag); }
// Функция копирует данные таблицы в бекап bool WriteTable(ITable itm, BinaryWriterCRC32 sm, BinaryWriter sd, int count, Log log) { log.Append("Begin read table: "); log.Append(itm.Key); log.Append(", count: "); log.Append(count); log.Append("\r\n"); var crc = new CRC32(); var crcerr = 0; var crcused = (itm.CurrentVersion.Mode & PageFileIOMode.CRC32) == PageFileIOMode.CRC32; var fs = itm.File.CreateStream(); var size = itm.CurrentVersion.RecordSize; var buf = new byte[size]; var map = itm.File.GetDeletedMap(); var ver = itm.CurrentVersion; var delta = size_time; var flag = true; if (crcused) { delta = size_time_crc; } fs.Position = PageFile.HeaderSize + size; for (int i = 0; i < count; ++i) { // Записываем позицию метаданных sm.Write(sd.BaseStream.Position); //Debug.WriteLine("Backup " + itm.Key + ", code: " + (i + 1) + ", offset:" + sd.BaseStream.Position); fs.Read(buf, 0, size); if (i + 1 == 1350685) { var bp = 0; } var time = 0l; var fact = 0l; // Читаем время и crc fixed(byte *ptr = &buf[size - delta]) { time = *(long *)ptr; if (crcused) { fact = *(int *)(ptr + size_time); } } // Пишем время if (map.Contains(i + 1)) { if (time == 0) { time = DateTime.Now.Ticks; } // если запись удалена sd.Write(-time); crc.Reset(); continue; } else { // если запись нормальная sd.Write(time); } // считаем crc данных и времени crc.Update(buf, 0, size - delta); crc.Update(time); // Быстрая проверка без данных переменной длинны if (fact != crc.Value) { flag = false; crcerr++; if (crcerr < 10) { log.Append("Warning reading: The object with code: ", i + 1, " crc32 check failed.\r\n"); } } crc.Reset(); crc.Update(time); // Массивы произвольной длинны if (ver.HasStorage) { for (var j = 0; j < ver.Structure.Length; ++j) { var fld = ver.Structure[j]; if (fld.IsStorage) { //Debug.WriteLine("Backup " + itm.Key + ", code: " + (i + 1) + ", field: " + fld.Name + " pos: " + sd.BaseStream.Position); fixed(byte *ptr = &buf[fld.Offset]) { var tmp = fld.Storage.ReadBytes(*((long *)ptr)); sd.Write(tmp.Length); sd.BaseStream.Write(tmp, 0, tmp.Length); crc.Update(tmp.Length); crc.Update(tmp, 0, tmp.Length); } } else { switch (fld.Size) { case 1: { sd.Write(buf[fld.Offset]); crc.Update(buf[fld.Offset]); break; } case 2: { fixed(byte *ptr = &buf[fld.Offset]) { var tmp = (char *)ptr; sd.Write(*tmp); crc.Update(*tmp); } break; } case 4: { fixed(byte *ptr = &buf[fld.Offset]) { var tmp = (uint *)ptr; sd.Write(*tmp); crc.Update(*tmp); } break; } case 8: { fixed(byte *ptr = &buf[fld.Offset]) { var tmp = (ulong *)ptr; sd.Write(*tmp); crc.Update(*tmp); } break; } case 16: { fixed(byte *ptr = &buf[fld.Offset]) { var tmp = (decimal *)ptr; sd.Write(*tmp); crc.Update(*tmp); } break; } } } } // Пишем CRC sd.Write(crc.Value); } else { // crc данных crc.Update(buf, 0, size - delta); // Пишем данные sd.BaseStream.Write(buf, 0, size - delta); // Пишем CRC sd.Write(crc.Value); } crc.Reset(); if (i > 0 && i % 100000 == 0) { log.Append("Progresss : ", i, "\r\n"); } } fs.Close(); return(flag); }
public void ResetCRC() { crc32.Reset(); }