public static TenantRelocationState GetTenantRelocationState(string tenantName, PartitionId partitionId, out bool isSourceTenant, bool readThrough = false)
        {
            if (string.IsNullOrEmpty(tenantName))
            {
                throw new ArgumentNullException("tenantName");
            }
            if (!ForestTenantRelocationsCache.IsTenantRelocationAllowed(partitionId.ForestFQDN))
            {
                isSourceTenant = true;
                return(new TenantRelocationState(partitionId.ForestFQDN, TenantRelocationStatus.NotStarted));
            }
            TenantRelocationStateCache         tenantRelocationStateCache = TenantRelocationStateCache.GetInstance();
            ExpiringTenantRelocationStateValue expiringTenantRelocationStateValue;

            if (!tenantRelocationStateCache.tenantRelocationStates.TryGetValue(tenantName, out expiringTenantRelocationStateValue) || expiringTenantRelocationStateValue.Expired || readThrough || TenantRelocationStateCache.IgnoreRelocationTimeConstraints())
            {
                TenantRelocationState tenantRelocationState = TenantRelocationStateCache.LoadTenantRelocationState(tenantName, partitionId);
                ExTraceGlobals.TenantRelocationTracer.TraceDebug(0L, "TenantRelocationStateCache::GetTenantRelocationState(): Inserting new TenantRelocationState value for tenant {0} to the cache: SourceForestFQDN={1}, SourceForestState={2}, TargetForestFQDN={3}, TargetForestState={4}, TargetOrganizationId={5}", new object[]
                {
                    tenantName,
                    tenantRelocationState.SourceForestFQDN,
                    tenantRelocationState.SourceForestState,
                    tenantRelocationState.TargetForestFQDN,
                    tenantRelocationState.TargetForestState,
                    (tenantRelocationState.TargetOrganizationId != null) ? tenantRelocationState.TargetOrganizationId.ToString() : "<null>"
                });
                expiringTenantRelocationStateValue = new ExpiringTenantRelocationStateValue(tenantRelocationState);
                tenantRelocationStateCache.AddOrUpdate(tenantName, expiringTenantRelocationStateValue);
            }
            if (expiringTenantRelocationStateValue.Value.TargetOrganizationId == null || expiringTenantRelocationStateValue.Value.TargetOrganizationId.OrganizationalUnit == null)
            {
                isSourceTenant = true;
            }
            else if (expiringTenantRelocationStateValue.Value.TargetOrganizationId.PartitionId != partitionId)
            {
                isSourceTenant = true;
            }
            else if (expiringTenantRelocationStateValue.Value.SourceForestFQDN == expiringTenantRelocationStateValue.Value.TargetForestFQDN)
            {
                isSourceTenant = (tenantName != expiringTenantRelocationStateValue.Value.TargetOrganizationId.OrganizationalUnit.Name);
            }
            else
            {
                isSourceTenant = false;
            }
            return(expiringTenantRelocationStateValue.Value);
        }
 private void AddOrUpdate(string tenantName, ExpiringTenantRelocationStateValue state)
 {
     lock (this.syncObject)
     {
         if (this.tenantRelocationStates.Count >= 25000)
         {
             int           num  = this.tenantRelocationStates.Count - 22500;
             List <string> list = new List <string>(num);
             foreach (KeyValuePair <string, ExpiringTenantRelocationStateValue> keyValuePair in this.tenantRelocationStates)
             {
                 if (keyValuePair.Value.Expired)
                 {
                     list.Add(keyValuePair.Key);
                 }
             }
             int num2 = num - list.Count;
             if (num2 > 0)
             {
                 foreach (KeyValuePair <string, ExpiringTenantRelocationStateValue> keyValuePair2 in this.tenantRelocationStates)
                 {
                     if (!keyValuePair2.Value.Expired)
                     {
                         list.Add(keyValuePair2.Key);
                         if (--num2 <= 0)
                         {
                             break;
                         }
                     }
                 }
             }
             foreach (string key in list)
             {
                 this.tenantRelocationStates.Remove(key);
             }
         }
         this.tenantRelocationStates[tenantName] = state;
     }
 }