Exemple #1
0
        /// <summary>Adds the given plan to the plan cache.</summary>
        /// <remarks>
        /// The plan is not contained within the cache after this call, it is assumed in use by the client.
        /// This call simply reserves storage and marks the plan as referenced for the LRU.
        /// </remarks>
        public void Add(ServerProcess process, string statement, int contextHashCode, ServerPlan plan)
        {
            CachedPlans      bumped = null;
            CachedPlanHeader header = GetPlanHeader(process, statement, contextHashCode);

            plan.Header             = header;
            plan.PlanCacheTimeStamp = process.Catalog.PlanCacheTimeStamp;

            lock (this)
            {
                if (_plans != null)
                {
                    CachedPlans plans;
                    if (!_plans.TryGetValue(header, out plans))
                    {
                        plans = new CachedPlans();
                    }
                    bumped = _plans.Reference(header, plans);
                }
            }

            if (bumped != null)
            {
                DisposeCachedPlans(process, bumped);
            }
        }
Exemple #2
0
 private void DisposeCachedPlans(ServerProcess process, CachedPlans plans)
 {
     foreach (ServerPlan plan in plans)
     {
         DisposeCachedPlan(process, plan);
     }
 }
Exemple #3
0
        /// <summary>Gets a cached plan for the given statement, if available.</summary>
        /// <remarks>
        /// If a plan is found, it is referenced for the LRU, and disowned by the cache.
        /// The client must call Release to return the plan to the cache.
        /// If no plan is found, null is returned and the cache is unaffected.
        /// </remarks>
        public ServerPlan Get(ServerProcess process, string statement, int contextHashCode)
        {
            ServerPlan       plan   = null;
            CachedPlanHeader header = GetPlanHeader(process, statement, contextHashCode);
            CachedPlans      bumped = null;

            lock (this)
            {
                if (_plans != null)
                {
                    CachedPlans plans;
                    if (_plans.TryGetValue(header, out plans))
                    {
                        for (int planIndex = plans.Count - 1; planIndex >= 0; planIndex--)
                        {
                            plan = plans[planIndex];
                            plans.RemoveAt(planIndex);
                            if (process.Catalog.PlanCacheTimeStamp > plan.PlanCacheTimeStamp)
                            {
                                DisposeCachedPlan(process, plan);
                                plan = null;
                            }
                            else
                            {
                                bumped = _plans.Reference(header, plans);
                                break;
                            }
                        }
                    }
                }
            }

            if (bumped != null)
            {
                DisposeCachedPlans(process, bumped);
            }

            if (plan != null)
            {
                plan.BindToProcess(process);
            }

            return(plan);
        }