Ejemplo n.º 1
0
        private XElement GetItemByNode(object[] node, XElement format)
        {
            if (format == null || format.Name != "record")
            {
                throw new Exception("Err: strange format");
            }
            if (node == null || (object[])node[1] == null)
            {
                return(new XElement("record"));
            }
            object[] type_dup = ((object[])node[1]).Cast <object[]>().FirstOrDefault(dup => (int)dup[0] == store.cod_rdftype);
            XElement xres     = new XElement("record", new XAttribute("id", store.Decode((int)node[0])),
                                             type_dup == null?null: new XAttribute("type", store.DecodeEntity((int)type_dup[1])),
                                             format.Elements().Where(fel => fel.Name == "field" || fel.Name == "direct" || fel.Name == "inverse")
                                             .SelectMany(fel =>
            {
                string prop   = fel.Attribute("prop").Value;
                int iprop     = store.Code(prop);
                int cod       = (int)node[0];
                object[] invs = null;
                if (fel.Name == "field")
                {
                    // Предполагаю, что значений может быть несколько
                    var query = ((object[])node[2]).Cast <object[]>()
                                .Where(dup => (int)dup[0] == iprop)
                                .Select(dup =>
                    {
                        return(new XElement("field", new XAttribute("prop", prop), (string)dup[1]));
                    });
                    return(query);
                }
                else if (fel.Name == "direct")
                {
                    // Предполагаю, что прямых ссылок с данным свойством может быть только одна
                    // найду соответствующую пару
                    object[] dupp = ((object[])node[1]).Cast <object[]>()
                                    .FirstOrDefault(dup => (int)dup[0] == iprop);
                    if (dupp == null)
                    {
                        return(new XElement[0]);
                    }
                    int itarget          = (int)dupp[1];
                    object[] target_node = (object[])store.GetRecord(itarget);
                    if (target_node == null)
                    {
                        return(new XElement[0]);                         // цели нет!
                    }
                    string rec_type = GetRecordType(target_node);
                    var rec_format  = fel.Elements("record").FirstOrDefault(r => r.Attribute("type")?.Value == rec_type);
                    if (rec_format == null)
                    {
                        rec_format = fel.Element("record");
                    }
                    return(Enumerable.Repeat <XElement>(
                               new XElement("direct", new XAttribute("prop", prop),
                                            GetItemByNode(target_node, rec_format),
                                            null), 1));
                }
                else
                {
                    // Предполагаю, что обратных ссылок с данным свойством может быть много
                    // Сначала вычислю группу обратных записей, если еще не вычислена
                    if (invs == null)
                    {
                        invs = store.GetRefers(cod).ToArray();
                        //invs = ((object[])store.GetRefers((int)node[0])).ToArray();
                    }
                    // Теперь надо сформировать множество элементов <inverse prop="..." <record ...
                    // Теоретически можно сгруппировать множество под одним inverse, но я не буду так делать
                    // здесь нам понадобятся только записи, где есть свойство и таргет
                    // Внутренний формат:
                    XElement subformat = fel.Element("record");
                    return(invs.Cast <object[]>().Where(r => ((object[])r[1])
                                                        .Cast <object[]>()
                                                        .Any(dup => (int)dup[0] == iprop && (int)dup[1] == cod))
                           .Select(r => new XElement("inverse", new XAttribute("prop", prop),
                                                     GetItemByNode((object[])store.GetRecord((int)r[0]), subformat))));
                }
            }),
                                             null);

            return(xres);
        }
Ejemplo n.º 2
0
        public static void Main20()
        {
            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
            System.Random rnd = new Random();
            //string path = "../../../../data/Databases/";
            string        path      = "C:/Home/data/Databases/";
            int           fnom      = 0;
            Func <Stream> GenStream = () => File.Open(path + (fnom++), FileMode.OpenOrCreate);

            Console.WriteLine("Start TestConsoleApp (Main32)");
            TripleRecordStore store = new TripleRecordStore(GenStream, path, new string[] {
                "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
                , "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"
            });

            int npersons     = 40_000;
            int nphotos      = npersons * 2;
            int nreflections = npersons * 6;

            bool toload = true;
            bool tocode = true;

            if (toload)
            {
                sw.Restart();
                store.Clear();
                var persons = Enumerable.Range(0, npersons).Select(i => npersons - i - 1)
                              .Select(c => new object[] { -c - 1, // Это "прямой" код не требующий кодирования через таблицу
                                                          new object[] { new object[] { 0, 3 } },
                                                          new object[] { new object[] { 1, "p" + c }, new object[] { 2, "" + 33 } } });
                var persons2 = Enumerable.Range(0, npersons).Select(i => npersons - i - 1)
                               .Select(c => store.CodeRecord(new object[] { "" + c,
                                                                            new object[] { new object[] { "http://www.w3.org/1999/02/22-rdf-syntax-ns#type", "http://fogid.net/o/person" } },
                                                                            new object[] { new object[] { "http://fogid.net/o/name", "p" + c }, new object[] { "http://fogid.net/o/age", "" + 33 } } }));
                var persons3 = Enumerable.Range(0, npersons).Select(i => npersons - i - 1)
                               .Select(c => store.CodeRecord(new object[] { "" + c, // Это "прямой" код не требующий кодирования через таблицу
                                                                            new object[] { new object[] { 0, 3 } },
                                                                            new object[] { new object[] { 1, "p" + c }, new object[] { 2, "" + 33 } } }));
                var photos = Enumerable.Range(0, nphotos).Select(i => nphotos - i - 1)
                             .Select(c => new object[] { -(c + npersons) - 1, // Это "прямой" код не требующий кодирования через таблицу
                                                         new object[] { new object[] { 0, 4 } },
                                                         new object[] { new object[] { 1, "f" + c } } });
                var photos2 = Enumerable.Range(0, nphotos).Select(i => nphotos - i - 1)
                              .Select(c => store.CodeRecord(new object[] { "" + (c + npersons),
                                                                           new object[] { new object[] { "http://www.w3.org/1999/02/22-rdf-syntax-ns#type", "http://fogid.net/o/photo-doc" } },
                                                                           new object[] { new object[] { "http://fogid.net/o/name", "f" + c } } }));
                var photos3 = Enumerable.Range(0, nphotos).Select(i => nphotos - i - 1)
                              .Select(c => store.CodeRecord(new object[] { "" + (c + npersons), // Это "прямой" код не требующий кодирования через таблицу
                                                                           new object[] { new object[] { 0, 4 } },
                                                                           new object[] { new object[] { 1, "f" + c } } }));
                var reflections = Enumerable.Range(0, nreflections).Select(i => nreflections - i - 1)
                                  .Select(c => new object[] { -(c + 3 * npersons) - 1, // Это "прямой" код не требующий кодирования через таблицу
                                                              new object[] { new object[] { 0, 5 },
                                                                             new object[] { 6, -1 - (rnd.Next(npersons)) },
                                                                             new object[] { 7, -1 - (rnd.Next(nphotos) + npersons) } },
                                                              new object[] { } });
                var reflections2 = Enumerable.Range(0, nreflections).Select(i => nreflections - i - 1)
                                   .Select(c => store.CodeRecord(new object[] { "" + (c + 3 * npersons),
                                                                                new object[] { new object[] { "http://www.w3.org/1999/02/22-rdf-syntax-ns#type", "http://fogid.net/o/reflection" },
                                                                                               new object[] { "http://fogid.net/o/reflected", "" + rnd.Next(npersons) },
                                                                                               new object[] { "http://fogid.net/o/in-doc", "" + (rnd.Next(nphotos) + npersons) } },
                                                                                new object[] { } }));
                var reflections3 = Enumerable.Range(0, nreflections).Select(i => nreflections - i - 1)
                                   .Select(c => store.CodeRecord(new object[] { "" + (c + 3 * npersons), // Это "прямой" код не требующий кодирования через таблицу
                                                                                new object[] { new object[] { 0, 5 },
                                                                                               new object[] { 6, "" + rnd.Next(npersons) },
                                                                                               new object[] { 7, "" + (rnd.Next(nphotos) + npersons) } },
                                                                                new object[] { } }));
                if (tocode)
                {
                    store.Load(persons2.Concat(photos2).Concat(reflections2));
                    //store.Load(persons3.Concat(photos3).Concat(reflections3));
                }
                else
                {
                    store.Load(persons.Concat(photos).Concat(reflections));
                }
                store.Build();
                sw.Stop();
                Console.WriteLine($"Load ok. duration={sw.ElapsedMilliseconds}");
            }
            //else
            {
                sw.Restart();
                store.Refresh();
                sw.Stop();
                Console.WriteLine($"Refresh for Phototeka {npersons} persons. Duration={sw.ElapsedMilliseconds}");
            }


            // ПОлукодирование иногда кодирование, иногда нет
            Func <int, int> HCode = nom => tocode?store.Code("" + nom) : -1 - nom;

            // Проверка
            int code = HCode(npersons * 2 / 3);

            var query1 = store.GetRecord(code);

            Console.WriteLine(store.ToTT(query1));

            // Скорость выполнения запросов
            int nprobe = 10000;

            sw.Restart();
            for (int i = 0; i < nprobe; i++)
            {
                int c  = HCode(rnd.Next(npersons));
                var ob = store.GetRecord(c);
            }
            sw.Stop();
            Console.WriteLine($"{nprobe} GetRecord() ok. duration={sw.ElapsedMilliseconds}");

            // Надо найти все фотографии, в которых отражается персона с выбранным (случайно) кодом.
            sw.Restart();
            int total = 0;

            nprobe = 1000;
            for (int i = 0; i < nprobe; i++)
            {
                int c      = HCode(rnd.Next(npersons));
                var query2 = store.GetRefers(c).Cast <object[]>().ToArray();
                var q3     = query2
                             .Select(ob => ((object[])ob[1]).Cast <object[]>()
                                     .First(dupl => (int)dupl[0] == 7));
                var q4 = q3
                         .Select(bb => store.GetRecord((int)bb[1])).ToArray();
                total += query2.Count();
            }
            sw.Stop();
            Console.WriteLine($"{nprobe} persons for photos ok. duration={sw.ElapsedMilliseconds} total={total}");

            //var likes = store.Like("p" + 666);
            //foreach (var like in likes)
            //{
            //    Console.WriteLine($"like {store.ToTT(like)}");
            //}

            sw.Restart();
            total = 0;
            for (int i = 0; i < 1000; i++)
            {
                string id = "p" + rnd.Next(npersons / 10 + 1, npersons);
                total += store.Like(id).Count();
            }
            sw.Stop();
            Console.WriteLine($"{nprobe} likes for persons ok. duration={sw.ElapsedMilliseconds} total={total}");
        }