public override void Unregister(V extension, Type key) { Object writeLock = GetWriteLock(); lock (writeLock) { base.Unregister(extension, key); ClassEntry <V> classEntry = CopyStructure(); LinkedHashMap <StrongKey <V>, List <DefEntry <V> > > definitionReverseMap = classEntry.definitionReverseMap; List <DefEntry <V> > weakEntriesOfStrongType = definitionReverseMap.Remove(new StrongKey <V>(extension, key)); if (weakEntriesOfStrongType == null) { return; } LinkedHashMap <Type, Object> typeToDefEntryMap = classEntry.typeToDefEntryMap; for (int a = weakEntriesOfStrongType.Count; a-- > 0;) { DefEntry <V> defEntry = weakEntriesOfStrongType[a]; Type registeredType = defEntry.type; Object value = typeToDefEntryMap.Get(registeredType); InterfaceFastList <DefEntry <V> > list = (InterfaceFastList <DefEntry <V> >)value; list.Remove(defEntry); if (list.Count == 0) { typeToDefEntryMap.Remove(registeredType); } TypeToDefEntryMapChanged(classEntry, registeredType); } this.classEntry = classEntry; } }
protected ClassEntry <V> CopyStructure() { ClassEntry <V> newClassEntry = new ClassEntry <V>(); LinkedHashMap <Type, Object> newTypeToDefEntryMap = newClassEntry.typeToDefEntryMap; LinkedHashMap <StrongKey <V>, List <DefEntry <V> > > newDefinitionReverseMap = newClassEntry.definitionReverseMap; IdentityHashMap <DefEntry <V>, DefEntry <V> > originalToCopyMap = new IdentityHashMap <DefEntry <V>, DefEntry <V> >(); { foreach (Entry <Type, Object> entry in classEntry.typeToDefEntryMap) { Type key = entry.Key; Object value = entry.Value; if (Object.ReferenceEquals(value, alreadyHandled)) { newTypeToDefEntryMap.Put(key, alreadyHandled); } else { InterfaceFastList <DefEntry <V> > list = (InterfaceFastList <DefEntry <V> >)value; InterfaceFastList <DefEntry <V> > newList = new InterfaceFastList <DefEntry <V> >(); IListElem <DefEntry <V> > pointer = list.First; while (pointer != null) { DefEntry <V> defEntry = pointer.ElemValue; DefEntry <V> newDefEntry = new DefEntry <V>(defEntry.extension, defEntry.type, defEntry.distance); originalToCopyMap.Put(defEntry, newDefEntry); newList.PushLast(newDefEntry); pointer = pointer.Next; } newTypeToDefEntryMap.Put(key, newList); } TypeToDefEntryMapChanged(newClassEntry, key); } } foreach (Entry <StrongKey <V>, List <DefEntry <V> > > entry in classEntry.definitionReverseMap) { List <DefEntry <V> > defEntries = entry.Value; List <DefEntry <V> > newDefEntries = new List <DefEntry <V> >(defEntries.Count); for (int a = 0, size = defEntries.Count; a < size; a++) { DefEntry <V> newDefEntry = originalToCopyMap.Get(defEntries[a]); if (newDefEntry == null) { throw new Exception("Must never happen"); } newDefEntries.Add(newDefEntry); } newDefinitionReverseMap.Put(entry.Key, newDefEntries); } return(newClassEntry); }
public void ClearWeakCache() { Object writeLock = GetWriteLock(); lock (writeLock) { ClassExtendableContainer <V> tempCC = new ClassExtendableContainer <V>("", ""); foreach (Entry <Type, Object> entry in this) { tempCC.Register((V)entry.Value, entry.Key); } this.classEntry = tempCC.classEntry; } }
public override void Register(V extension, Type key) { Object writeLock = GetWriteLock(); lock (writeLock) { base.Register(extension, key); ClassEntry <V> classEntry = CopyStructure(); AppendRegistration(key, key, extension, 0, classEntry); CheckToWeakRegisterExistingTypes(key, extension, classEntry); CheckToWeakRegisterExistingExtensions(key, classEntry); this.classEntry = classEntry; } }
protected bool CheckToWeakRegisterExistingTypes(Type type, V extension, ClassEntry <V> classEntry) { bool changesHappened = false; foreach (Entry <Type, Object> entry in classEntry.typeToDefEntryMap) { Type existingRequestedType = entry.Key; int priorityForExistingRequestedType = GetDistanceForType(existingRequestedType, type); if (priorityForExistingRequestedType == NO_VALID_DISTANCE) { continue; } changesHappened |= AppendRegistration(type, existingRequestedType, extension, priorityForExistingRequestedType, classEntry); } return(changesHappened); }
protected override void TypeToDefEntryMapChanged(ClassEntry <V> classEntry, Type key) { Object obj = classEntry.typeToDefEntryMap.Get(key); if (obj == null) { classEntry.Remove(key); return; } if (obj == alreadyHandled) { classEntry.Put(key, alreadyHandled); return; } Object existingItem = classEntry.Get(key); List <V> list = (List <V>)(existingItem == alreadyHandled ? null : existingItem); if (list == null) { list = new List <V>(); classEntry.Put(key, list); } if (obj is DefEntry <V> ) { V extension = ((DefEntry <V>)obj).extension; if (!list.Contains(extension)) { list.Add(extension); } return; } IListElem <DefEntry <V> > pointer = ((InterfaceFastList <DefEntry <V> >)obj).First; while (pointer != null) { V extension = pointer.ElemValue.extension; if (!list.Contains(extension)) { list.Add(extension); } pointer = pointer.Next; } }
protected bool CheckToWeakRegisterExistingExtensions(Type type, ClassEntry <V> classEntry) { bool changesHappened = false; foreach (Entry <StrongKey <V>, List <DefEntry <V> > > entry in classEntry.definitionReverseMap) { StrongKey <V> strongKey = entry.Key; Type registeredStrongType = strongKey.strongType; int distance = GetDistanceForType(type, registeredStrongType); if (distance == NO_VALID_DISTANCE) { continue; } List <DefEntry <V> > defEntries = entry.Value; for (int a = defEntries.Count; a-- > 0;) { DefEntry <V> defEntry = defEntries[a]; changesHappened |= AppendRegistration(registeredStrongType, type, defEntry.extension, distance, classEntry); } } return(changesHappened); }
public override V GetExtension(Type key) { if (key == null) { return(default(V)); } Object extension = this.classEntry.Get(key); if (extension == null) { Object writeLock = GetWriteLock(); lock (writeLock) { extension = this.classEntry.Get(key); if (extension == null) { ClassEntry <V> classEntry = CopyStructure(); classEntry.Put(key, alreadyHandled); classEntry.typeToDefEntryMap.Put(key, alreadyHandled); CheckToWeakRegisterExistingExtensions(key, classEntry); this.classEntry = classEntry; extension = classEntry.Get(key); if (extension == null) { return(default(V)); } } } } if (Object.ReferenceEquals(extension, alreadyHandled)) { // Already tried return(default(V)); } return((V)extension); }
protected virtual void TypeToDefEntryMapChanged(ClassEntry <V> classEntry, Type key) { Object obj = classEntry.typeToDefEntryMap.Get(key); if (obj == null) { classEntry.Remove(key); return; } if (obj == alreadyHandled) { classEntry.Put(key, alreadyHandled); return; } if (obj is DefEntry <V> ) { classEntry.Put(key, ((DefEntry <V>)obj).extension); return; } DefEntry <V> firstDefEntry = ((InterfaceFastList <DefEntry <V> >)obj).First.ElemValue; classEntry.Put(key, firstDefEntry.extension); }
protected bool AppendRegistration(Type strongType, Type type, V extension, int distance, ClassEntry <V> classEntry) { LinkedHashMap <Type, Object> typeToDefEntryMap = classEntry.typeToDefEntryMap; Object fastList = typeToDefEntryMap.Get(type); if (fastList != null && !Object.ReferenceEquals(fastList, alreadyHandled)) { IListElem <DefEntry <V> > pointer = ((InterfaceFastList <DefEntry <V> >)fastList).First; while (pointer != null) { DefEntry <V> existingDefEntry = pointer.ElemValue; if (Object.ReferenceEquals(existingDefEntry.extension, extension) && existingDefEntry.distance == distance) { // DefEntry already exists with same distance return(false); } pointer = pointer.Next; } } if (fastList == null || Object.ReferenceEquals(fastList, alreadyHandled)) { fastList = new InterfaceFastList <DefEntry <V> >(); typeToDefEntryMap.Put(type, fastList); } DefEntry <V> defEntry = new DefEntry <V>(extension, type, distance); LinkedHashMap <StrongKey <V>, List <DefEntry <V> > > definitionReverseMap = classEntry.definitionReverseMap; StrongKey <V> strongKey = new StrongKey <V>(extension, strongType); List <DefEntry <V> > typeEntries = definitionReverseMap.Get(strongKey); if (typeEntries == null) { typeEntries = new List <DefEntry <V> >(); definitionReverseMap.Put(strongKey, typeEntries); } typeEntries.Add(defEntry); InterfaceFastList <DefEntry <V> > .InsertOrdered((InterfaceFastList <DefEntry <V> >) fastList, defEntry); TypeToDefEntryMapChanged(classEntry, type); return(true); }