/// <summary> /// Инициирование базы данных /// </summary> /// <param name="connectionstring">префикс варианта базы данных ts:, после этого - директория для оператиыной БД</param> private void Init(string connectionstring) { if (connectionstring != null && connectionstring.StartsWith("trs:")) { dbfolder = connectionstring.Substring(4); } if (File.Exists(dbfolder + "0.bin")) { _firsTime = false; } Stream GenStream() => new FileStream(dbfolder + (fileNo++) + ".bin", FileMode.OpenOrCreate, FileAccess.ReadWrite); Store = new TripleRecordStore(GenStream, dbfolder, new[] { "http://www.w3.org/1999/02/22-rdf-syntax-ns#type", "http://fogid.net/o/delete", "http://fogid.net/o/name", "http://fogid.net/o/age", "http://fogid.net/o/person", "http://fogid.net/o/photo-doc", "http://fogid.net/o/reflection", "http://fogid.net/o/reflected", "http://fogid.net/o/in-doc" }); if (!_firsTime) { Store.DynaBuild(); } Store.Flush(); }
internal bool firsttime = true; // Отмечает (вычисляет) ситуацию, когда базу данных обязательно нужно строить. // Важные коды //private int cod_rdftype = 0; //private int cod_name; //private int cod_delete; /// <summary> /// Инициирование базы данных /// </summary> /// <param name="connectionstring">префикс варианта базы данных ts:, после этого - директория для оператиыной БД</param> public override void Init(string connectionstring) { if (connectionstring != null && connectionstring.StartsWith("trs:")) { dbfolder = connectionstring.Substring(4); } if (File.Exists(dbfolder + "0.bin")) { firsttime = false; } Func <Stream> GenStream = () => new FileStream(dbfolder + (file_no++) + ".bin", FileMode.OpenOrCreate, FileAccess.ReadWrite); store = new TripleRecordStore(GenStream, dbfolder, new string[] { "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" , "http://fogid.net/o/delete" , "http://fogid.net/o/name" , "http://fogid.net/o/age" , "http://fogid.net/o/person" , "http://fogid.net/o/photo-doc" , "http://fogid.net/o/reflection" , "http://fogid.net/o/reflected" , "http://fogid.net/o/in-doc" }); // Вычисление "важных" кодов //cod_rdftype = store.CodeEntity("http://www.w3.org/1999/02/22-rdf-syntax-ns#type"); // Зафиксирован? 0; //cod_delete = store.CodeEntity("http://fogid.net/o/delete"); //cod_name = store.CodeEntity("http://fogid.net/o/name"); //if (!firsttime) store.DynaBuild(); store.Refresh(); store.Flush(); }
// Новая реализация загрузки базы данных private void FillDb(IEnumerable <FogInfo> fogFlow) { // Пока каждый раз чистим базу данных Store.Clear(); // Вычисление "важных" кодов var codRdftype = Store.CodeEntity("http://www.w3.org/1999/02/22-rdf-syntax-ns#type"); // Зафиксирован? 0; // Готовим битовый массив для отметки того, что хеш id уже "попадал" в этот бит int rang = 24; // пока предполагается, что число записей (много) меньше 16 млн. int mask = ~((-1) << rang); int baVolume = mask + 1; System.Collections.BitArray bitArr = new System.Collections.BitArray(baVolume); // Хеш-функция будет ограничена rang разрядами, массив и функция нужны только временно int Hash(string s) => s.GetHashCode() & mask; // Словарь, фиксирующий максимальную дату для заданного идентификатора, первая запись не учитывается Dictionary <string, DateTime> lastDefs = new Dictionary <string, DateTime>(); // Первый проход сканирования фог-файлов. В этом проходе определяется набор повторно определенных записей и // формируется словарь lastDefs foreach (FogInfo fi in fogFlow) { switch (fi.Vid) { // Чтение фога case ".fog": { fi.Fogx = XElement.Load(fi.Pth); foreach (XElement xElement in fi.Fogx.Elements()) { XElement record = ConvertXElement(xElement); // Обработаем "странные" delete и replace if (record.Name == ONames.fogi + "delete") { string idd = record.Attribute(ONames.rdfabout)?.Value ?? record.Attribute("id")?.Value; // Если нет атрибута mT, временная отметка устанавливается максимальной, чтобы "забить" другие отметки string mTvalue = record.Attribute("mT") == null ? DateTime.MaxValue.ToString(CultureInfo.InvariantCulture) : record.Attribute("mT")?.Value; CheckAndSet(bitArr, Hash, lastDefs, idd, mTvalue); continue; } if (record.Name == ONames.fogi + "substitute") { continue; // пока не обрабатываем } string id = record.Attribute(ONames.rdfabout)?.Value; CheckAndSet(bitArr, Hash, lastDefs, id, record.Attribute("mT")?.Value); } fi.Fogx = null; break; } case ".fogp": break; } } // Второй проход сканирования фог-файлов. В этом проходе, для каждого фога формируется поток записей в // объектном представлении, потом этот поток добавляется в store foreach (FogInfo fi in fogFlow) { switch (fi.Vid) { // Чтение фога case ".fog": case ".fogx": { fi.Fogx = XElement.Load(fi.Pth); IEnumerable <object> flow = fi.Fogx.Elements() .Select(xrec => ConvertXElement(xrec)) // Обработаем delete и replace. delete доминирует (по времени), но в выходной поток ничего не попадает // substitute - не обрабатываем .Where(record => record.Name != ONames.fogi + "delete" && record.Name != ONames.fogi + "substitute") // Отфильтруем записи с малыми временами. т.е. если идентификатор есть в словаре, но он меньше. // Если он больше, то не фильтруем, а словарный вход корректируем .Where(record => { var xAbout = record.Attribute(ONames.rdfabout); if (xAbout == null) { return(true); } string id = xAbout.Value; if (!lastDefs.ContainsKey(id)) { return(true); } DateTime mT = DateTime.MinValue; string mTvalue = record.Attribute("mT")?.Value; if (mTvalue != null) { mT = DateTime.Parse(mTvalue); } DateTime last = lastDefs[id]; if (mT < last) { return(false); // пропускаем } if (mT == last) { return(true); // берем } // if(mT > last) // берем и корректируем last { lastDefs.Remove(id); lastDefs.Add(id, mT); return(true); } }) .Select(record => { string id = record.Attribute(ONames.rdfabout).Value; int rec_type = Store.CodeEntity(ONames.fog + record.Name.LocalName); int id_ent = Store.CodeEntity(id); object[] orecord = new object[] { id_ent, (new object[] { new object[] { codRdftype, rec_type } }).Concat( record.Elements().Where(el => el.Attribute(ONames.rdfresource) != null) .Select(subel => { int prop = Store.CodeEntity( subel.Name.NamespaceName + subel.Name.LocalName); return(new object[] { prop, Store.CodeEntity(subel.Attribute(ONames.rdfresource).Value) }); })).ToArray(), record.Elements().Where(el => el.Attribute(ONames.rdfresource) == null) .Select(subel => { int prop = Store.CodeEntity(subel.Name.NamespaceName + subel.Name.LocalName); return(new object[] { prop, subel.Value }); }) .ToArray() }; return(orecord); }); Store.Load(flow); fi.Fogx = null; break; } case ".fogp": break; } } Store.Build(); Store.Flush(); GC.Collect(); }