/// <summary> /// Internal recursive traversal for conversion. /// </summary> private static Util.Automaton.State Convert(State s, IdentityHashMap <State, Lucene.Net.Util.Automaton.State> visited) { if (visited.TryGetValue(s, out Util.Automaton.State converted) && converted != null) { return(converted); } converted = new Util.Automaton.State(); converted.Accept = s.is_final; visited[s] = converted; int i = 0; int[] labels = s.labels; foreach (DaciukMihovAutomatonBuilder.State target in s.states) { converted.AddTransition(new Transition(labels[i++], Convert(target, visited))); } return(converted); }
internal FieldsReader(PerFieldDocValuesFormat outerInstance, FieldsReader other) { this.outerInstance = outerInstance; IDictionary <DocValuesProducer, DocValuesProducer> oldToNew = new IdentityHashMap <DocValuesProducer, DocValuesProducer>(); // First clone all formats foreach (KeyValuePair <string, DocValuesProducer> ent in other.formats) { DocValuesProducer values = ent.Value; formats[ent.Key] = values; oldToNew[ent.Value] = values; } // Then rebuild fields: foreach (KeyValuePair <string, DocValuesProducer> ent in other.fields) { DocValuesProducer producer; oldToNew.TryGetValue(ent.Value, out producer); Debug.Assert(producer != null); fields[ent.Key] = producer; } }
/* * Non-recursive version of object descend. this consumes more memory than recursive in-depth * traversal but prevents stack overflows on long chains of objects * or complex graphs (a max. recursion depth on my machine was ~5000 objects linked in a chain * so not too much). */ private static long MeasureObjectSize(object root) { // Objects seen so far. IdentityHashSet <object> seen = new IdentityHashSet <object>(); // Class cache with reference Field and precalculated shallow size. HashMap <Type, ClassCache> classCache = new IdentityHashMap <Type, ClassCache>(); // Stack of objects pending traversal. Recursion caused stack overflows. Stack <object> stack = new Stack <object>(); stack.Push(root); long totalSize = 0; while (stack.Count > 0) { object ob = stack.Pop(); if (ob == null || seen.Contains(ob)) { continue; } seen.Add(ob); Type obClazz = ob.GetType(); if (obClazz.Equals(typeof(string))) { // LUCENENET specific - we can get a closer estimate of a string // by using simple math. Reference: http://stackoverflow.com/a/8171099. // This fixes the TestSanity test. totalSize += (2 * (((string)ob).Length + 1)); } if (obClazz.IsArray) { /* * Consider an array, possibly of primitive types. Push any of its references to * the processing stack and accumulate this array's shallow size. */ long size = NUM_BYTES_ARRAY_HEADER; Array array = (Array)ob; int len = array.Length; if (len > 0) { Type componentClazz = obClazz.GetElementType(); if (componentClazz.GetTypeInfo().IsPrimitive) { size += (long)len * primitiveSizes[componentClazz]; } else { size += (long)NUM_BYTES_OBJECT_REF * len; // Push refs for traversal later. for (int i = len; --i >= 0;) { object o = array.GetValue(i); if (o != null && !seen.Contains(o)) { stack.Push(o); } } } } totalSize += AlignObjectSize(size); } else { /* * Consider an object. Push any references it has to the processing stack * and accumulate this object's shallow size. */ try { if (!classCache.TryGetValue(obClazz, out ClassCache cachedInfo) || cachedInfo == null) { classCache[obClazz] = cachedInfo = CreateCacheEntry(obClazz); } foreach (FieldInfo f in cachedInfo.ReferenceFields) { // Fast path to eliminate redundancies. object o = f.GetValue(ob); if (o != null && !seen.Contains(o)) { stack.Push(o); } } totalSize += cachedInfo.AlignedShallowInstanceSize; } catch (Exception e) { // this should never happen as we enabled setAccessible(). throw new Exception("Reflective field access failed?", e); } } } // Help the GC (?). seen.Clear(); stack.Clear(); classCache.Clear(); return(totalSize); }