예제 #1
0
        public static void DumpLeaksCode(this IObjectDB db)
        {
            var leakedObjects      = new Dictionary <ulong, bool>();
            var leakedDictionaries = new Dictionary <ulong, bool>();

            using var tr      = db.StartReadOnlyTransaction();
            using var visitor = new FindUnusedKeysVisitor();
            visitor.ImportAllKeys(tr);
            visitor.Iterate(tr);
            foreach (var unseenKey in visitor.UnseenKeys())
            {
                var isDict   = unseenKey.Key[0] == 2;
                var isObject = unseenKey.Key[0] == 1;

                var r = new ByteArrayReader(unseenKey.Key);
                r.SkipUInt8();
                var oid = r.ReadVUInt64();

                if (isDict)
                {
                    leakedDictionaries.TryAdd(oid, false);
                }
                else if (isObject)
                {
                    leakedObjects.TryAdd(oid, false);
                }
            }

            WriteSplitIdList(leakedDictionaries.Keys, "dicts", 1000);
            WriteSplitIdList(leakedObjects.Keys, "objs", 1000);
        }
예제 #2
0
 string FindLeaks()
 {
     using (var visitor = new FindUnusedKeysVisitor())
     {
         using (var tr = _db.StartReadOnlyTransaction())
         {
             visitor.ImportAllKeys(tr);
             visitor.Iterate(tr);
             return(DumpUnseenKeys(visitor, " "));
         }
     }
 }
예제 #3
0
 void AssertNoLeaksInDb()
 {
     using (var visitor = new FindUnusedKeysVisitor())
     {
         using (var tr = _db.StartReadOnlyTransaction())
         {
             visitor.ImportAllKeys(tr);
             visitor.Iterate(tr);
             Assert.Empty(visitor.UnseenKeys());
         }
     }
 }
예제 #4
0
        static void DumpUnseenKeys(this FindUnusedKeysVisitor visitor)
        {
            foreach (var unseenKey in visitor.UnseenKeys())
            {
                foreach (var b in unseenKey.Key)
                {
                    Console.Write(' ');
                    Console.Write(b.ToString("X2"));
                }

                Console.Write(" Value len:");
                Console.WriteLine(unseenKey.ValueSize);
            }
        }
예제 #5
0
        static string DumpUnseenKeys(FindUnusedKeysVisitor visitor, string concat)
        {
            var builder = new StringBuilder();

            foreach (var unseenKey in visitor.UnseenKeys())
            {
                if (builder.Length > 0)
                {
                    builder.Append(concat);
                }
                foreach (var b in unseenKey.Key)
                {
                    builder.Append(b.ToString("X2"));
                }
                builder.Append(" Value len:");
                builder.Append(unseenKey.ValueSize);
            }
            return(builder.ToString());
        }
예제 #6
0
        public static void DumpLeaks(this IObjectDB db)
        {
            using (var tr = db.StartReadOnlyTransaction())
                using (var visitor = new FindUnusedKeysVisitor())
                {
                    visitor.ImportAllKeys(tr);
                    var iterator = visitor.Iterate(tr);
                    visitor.DumpUnseenKeys();
                    var leakedObjects = new List <ulong>();
                    foreach (var unseenKey in visitor.UnseenKeys())
                    {
                        if (unseenKey.Key[0] == 1)
                        {
                            try
                            {
                                var r = new ByteArrayReader(unseenKey.Key);
                                r.SkipUInt8();
                                var oid = r.ReadVUInt64();
                                leakedObjects.Add(oid);
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine($"Leak found but error has occured while reading: {ex.Message}");
                            }
                        }
                    }

                    if (leakedObjects.Count > 0)
                    {
                        Console.WriteLine("--- OBJECTS ---");
                        var consoleVisitor = new ToConsoleVisitorNice();
                        foreach (var oid in leakedObjects)
                        {
                            iterator.IterateUnseenOid(oid, consoleVisitor);
                            Console.WriteLine("------");
                        }
                    }
                }
        }
예제 #7
0
        public void FindAndRemovesUnusedKeys()
        {
            StoreJobInDictionary("programming", "code");
            StoreJobInDictionary("chess", "mate");
            using (var tr = _db.StartTransaction())
            {
                var sports = tr.Singleton <Directory>();
                sports.Dir["programming"] = new ODBIteratorTest.JobMap();
                tr.Commit();
            }

            using (var visitor = new FindUnusedKeysVisitor())
            {
                using (var tr = _db.StartReadOnlyTransaction())
                {
                    visitor.ImportAllKeys(tr);
                    visitor.Iterate(tr);
                }
                var report = DumpUnseenKeys(visitor, "\r\n");
                this.Assent(report);

                using (var tr = _db.StartTransaction())
                {
                    visitor.DeleteUnused(tr);
                    tr.Commit();
                }
            }
            ReopenDb();

            AssertNoLeaksInDb();
            using (var tr = _db.StartReadOnlyTransaction())
            {
                //check that db has is not broken after removing unused keys
                var sports = tr.Singleton <Directory>();
                Assert.Equal("mate", sports.Dir["chess"].Jobs[0].Duty.Name);
            }
        }