public override void Unregister(V extension, ConversionKey key) { ParamChecker.AssertParamNotNull(extension, "extension"); ParamChecker.AssertParamNotNull(key, "key"); Object writeLock = GetWriteLock(); lock (writeLock) { base.Unregister(extension, key); ClassTupleEntry <V> classEntry = CopyStructure(); HashMap <Strong2Key <V>, List <Def2Entry <V> > > definitionReverseMap = classEntry.definitionReverseMap; List <Def2Entry <V> > weakEntriesOfStrongType = definitionReverseMap.Remove(new Strong2Key <V>(extension, key)); if (weakEntriesOfStrongType == null) { return; } HashMap <ConversionKey, Object> typeToDefEntryMap = classEntry.typeToDefEntryMap; for (int a = weakEntriesOfStrongType.Count; a-- > 0;) { Def2Entry <V> defEntry = weakEntriesOfStrongType[a]; ConversionKey registeredKey = new ConversionKey(defEntry.sourceType, defEntry.targetType); Object value = typeToDefEntryMap.Get(registeredKey); InterfaceFastList <Def2Entry <V> > list = (InterfaceFastList <Def2Entry <V> >)value; list.Remove(defEntry); if (list.Count == 0) { typeToDefEntryMap.Remove(registeredKey); } TypeToDefEntryMapChanged(classEntry, registeredKey); } this.classEntry = classEntry; } }
public override V GetExtension(ConversionKey key) { Object extension = this.classEntry.Get(key); if (extension == null) { Object writeLock = GetWriteLock(); lock (writeLock) { extension = this.classEntry.Get(key); if (extension == null) { ClassTupleEntry <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 ClassTupleEntry <V> CopyStructure() { ClassTupleEntry <V> newClassEntry = new ClassTupleEntry <V>(); HashMap <ConversionKey, Object> newTypeToDefEntryMap = newClassEntry.typeToDefEntryMap; HashMap <Strong2Key <V>, List <Def2Entry <V> > > newDefinitionReverseMap = newClassEntry.definitionReverseMap; IdentityHashMap <Def2Entry <V>, Def2Entry <V> > originalToCopyMap = new IdentityHashMap <Def2Entry <V>, Def2Entry <V> >(); foreach (Entry <ConversionKey, Object> entry in classEntry.typeToDefEntryMap) { ConversionKey key = entry.Key; Object value = entry.Value; if (Object.ReferenceEquals(value, alreadyHandled)) { newTypeToDefEntryMap.Put(key, alreadyHandled); } else { InterfaceFastList <Def2Entry <V> > list = (InterfaceFastList <Def2Entry <V> >)value; InterfaceFastList <Def2Entry <V> > newList = new InterfaceFastList <Def2Entry <V> >(); IListElem <Def2Entry <V> > pointer = list.First; while (pointer != null) { Def2Entry <V> defEntry = pointer.ElemValue; Def2Entry <V> newDefEntry = new Def2Entry <V>(defEntry.extension, defEntry.sourceType, defEntry.targetType, defEntry.sourceDistance, defEntry.targetDistance); originalToCopyMap.Put(defEntry, newDefEntry); newList.PushLast(newDefEntry); pointer = pointer.Next; } newTypeToDefEntryMap.Put(key, newList); } TypeToDefEntryMapChanged(newClassEntry, key); } foreach (Entry <Strong2Key <V>, List <Def2Entry <V> > > entry in classEntry.definitionReverseMap) { List <Def2Entry <V> > defEntries = entry.Value; List <Def2Entry <V> > newDefEntries = new List <Def2Entry <V> >(defEntries.Count); for (int a = 0, size = defEntries.Count; a < size; a++) { Def2Entry <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 override void Register(V extension, ConversionKey key) { ParamChecker.AssertParamNotNull(extension, "extension"); ParamChecker.AssertParamNotNull(key, "key"); Object writeLock = GetWriteLock(); lock (writeLock) { base.Register(extension, key); ClassTupleEntry <V> classEntry = CopyStructure(); AppendRegistration(key, key, extension, 0, 0, classEntry); CheckToWeakRegisterExistingTypes(key, extension, classEntry); CheckToWeakRegisterExistingExtensions(key, classEntry); this.classEntry = classEntry; } }
protected bool AppendRegistration(ConversionKey strongTypeKey, ConversionKey key, V extension, int sourceDistance, int targetDistance, ClassTupleEntry <V> classEntry) { HashMap <ConversionKey, Object> typeToDefEntryMap = classEntry.typeToDefEntryMap; Object fastList = typeToDefEntryMap.Get(key); if (fastList != null && fastList != alreadyHandled) { IListElem <Def2Entry <V> > pointer = ((InterfaceFastList <Def2Entry <V> >)fastList).First; while (pointer != null) { Def2Entry <V> existingDefEntry = pointer.ElemValue; if (Object.ReferenceEquals(existingDefEntry.extension, extension) && existingDefEntry.sourceDistance == sourceDistance && existingDefEntry.targetDistance == targetDistance) { // DefEntry already exists with same distance return(false); } pointer = pointer.Next; } } if (fastList == null || Object.ReferenceEquals(fastList, alreadyHandled)) { fastList = new InterfaceFastList <Def2Entry <V> >(); typeToDefEntryMap.Put(key, fastList); } Def2Entry <V> defEntry = new Def2Entry <V>(extension, key.SourceType, key.TargetType, sourceDistance, targetDistance); HashMap <Strong2Key <V>, List <Def2Entry <V> > > definitionReverseMap = classEntry.definitionReverseMap; Strong2Key <V> strongKey = new Strong2Key <V>(extension, strongTypeKey); List <Def2Entry <V> > typeEntries = definitionReverseMap.Get(strongKey); if (typeEntries == null) { typeEntries = new List <Def2Entry <V> >(); definitionReverseMap.Put(strongKey, typeEntries); } typeEntries.Add(defEntry); InterfaceFastList <Def2Entry <V> > .InsertOrdered((InterfaceFastList <Def2Entry <V> >) fastList, defEntry); TypeToDefEntryMapChanged(classEntry, key); return(true); }
protected void TypeToDefEntryMapChanged(ClassTupleEntry <V> classEntry, ConversionKey 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 Def2Entry <V> ) { classEntry.Put(key, ((Def2Entry <V>)obj).extension); return; } Def2Entry <V> firstDefEntry = ((InterfaceFastList <Def2Entry <V> >)obj).First.ElemValue; classEntry.Put(key, firstDefEntry.extension); }
protected bool CheckToWeakRegisterExistingTypes(ConversionKey key, V extension, ClassTupleEntry <V> classEntry) { bool changesHappened = false; foreach (Entry <ConversionKey, Object> entry in classEntry.typeToDefEntryMap) { ConversionKey existingRequestedKey = entry.Key; int sourceDistance = ClassExtendableContainer <V> .GetDistanceForType(existingRequestedKey.SourceType, key.SourceType); if (sourceDistance == ClassExtendableContainer <V> .NO_VALID_DISTANCE) { continue; } int targetDistance = ClassExtendableContainer <V> .GetDistanceForType(key.TargetType, existingRequestedKey.TargetType); if (targetDistance == ClassExtendableContainer <V> .NO_VALID_DISTANCE) { continue; } changesHappened |= AppendRegistration(key, existingRequestedKey, extension, sourceDistance, targetDistance, classEntry); } return(changesHappened); }
protected bool CheckToWeakRegisterExistingExtensions(ConversionKey conversionKey, ClassTupleEntry <V> classEntry) { bool changesHappened = false; foreach (Entry <Strong2Key <V>, List <Def2Entry <V> > > entry in classEntry.definitionReverseMap) { Strong2Key <V> strongKey = entry.Key; ConversionKey registeredStrongKey = strongKey.key; int sourceDistance = ClassExtendableContainer <V> .GetDistanceForType(conversionKey.SourceType, registeredStrongKey.SourceType); if (sourceDistance == ClassExtendableContainer <V> .NO_VALID_DISTANCE) { continue; } int targetDistance = ClassExtendableContainer <V> .GetDistanceForType(registeredStrongKey.TargetType, conversionKey.TargetType); if (targetDistance == ClassExtendableContainer <V> .NO_VALID_DISTANCE) { continue; } List <Def2Entry <V> > defEntries = entry.Value; for (int a = defEntries.Count; a-- > 0;) { Def2Entry <V> defEntry = defEntries[a]; changesHappened |= AppendRegistration(registeredStrongKey, conversionKey, defEntry.extension, sourceDistance, targetDistance, classEntry); } } return(changesHappened); }