예제 #1
0
        private static void CacheMethodCall(object oParameters)
        {
            CacheMethodCallParams parameters = (CacheMethodCallParams)oParameters;

            try {
                Monitor.Enter(DynamicLock.Get(CACHING_LOCK_TYPE, parameters.CachingKey));
                parameters.Method._mi.Invoke(null, (new object[] { parameters.Request, parameters.Reply.Result, parameters.Reply.Error }));

                if (!parameters.Reply.Error.Exists)
                {
                    ResultCache.CacheResult(
                        parameters.Method.Id,
                        parameters.ResultKey,
                        parameters.Request.ParameterSet.ToXml().ToXElement(),
                        parameters.Reply.Result.Raw.ToXElement()
                        );
                }
            }
            catch (Exception e) {
                Manager.LogFault(parameters.Request, parameters.Reply, parameters.Method, "AsynchronousInvocationException", e);
            }
            finally {
                lock (DynamicLock.Lock) {
                    Monitor.Exit(DynamicLock.Get(CACHING_LOCK_TYPE, parameters.CachingKey));
                    DynamicLock.Remove(CACHING_LOCK_TYPE, parameters.CachingKey);
                }
            }
        }
예제 #2
0
파일: Node.cs 프로젝트: mikeblakeuk/MNP
        private void RemoveFromCache(bool localOnly, string id)
        {
            if (String.IsNullOrEmpty(id))
            {
                throw new ArgumentException("The key cannot be null or empty", "id");
            }

            ResultCache.Remove(id, localOnly);

            if (!localOnly)
            {
                Task.Run(() =>
                {
                    InterNodeCommunicationMessage msg = new InterNodeCommunicationMessage {
                        Tag = id, IsLocalOnly = true, MessageType = InterNodeMessageType.RemoveFromCache
                    };
                    // not sure this is valid as its non deterministic
                    lock (KnownNodes)
                    {
                        foreach (var el in KnownNodes)
                        {
                            SendToNode(el, InterNodeCommunicationMessageSerialiser.Serialise(msg));
                        }
                    }
                });
            }
        }
        private ServiceCallSite TryCreateExact(ServiceDescriptor descriptor, Type serviceType, CallSiteChain callSiteChain, int slot)
        {
            if (serviceType == descriptor.ServiceType)
            {
                ServiceCallSite callSite;
                var             lifetime = new ResultCache(descriptor.Lifetime, serviceType, slot);
                if (descriptor.ImplementationInstance != null)
                {
                    callSite = new ConstantCallSite(descriptor.ServiceType, descriptor.ImplementationInstance);
                }
                else if (descriptor.ImplementationFactory != null)
                {
                    callSite = new FactoryCallSite(lifetime, descriptor.ServiceType, descriptor.ImplementationFactory);
                }
                else if (descriptor.ImplementationType != null)
                {
                    callSite = CreateConstructorCallSite(lifetime, descriptor.ServiceType, descriptor.ImplementationType, callSiteChain);
                }
                else
                {
                    throw new InvalidOperationException("Invalid service descriptor");
                }

                return(callSite);
            }

            return(null);
        }
예제 #4
0
        /// ------------------------------------------------------------------------------------
        public bool Search(bool returnCountOnly, out int resultCount)
        {
            ResultCache = (returnCountOnly ? null : new WordListCache());
            resultCount = 0;

            foreach (var wentry in _project.WordCache)
            {
                if (ReportProgressAction != null)
                {
                    ReportProgressAction();
                }

                // Get a list of word(s) for this entry. If the query's IncludeAllUncertainPossibilities
                // flag is set, there will be multiple words, one for each uncertain possibility.
                // Otherwise there will be only one. Each word is delivered in the form of an array of
                // phones.
                var wordsList = (_query.IncludeAllUncertainPossibilities && wentry.ContiansUncertainties ?
                                 wentry.GetAllPossibleUncertainWords(false) : new[] { wentry.Phones });

                foreach (var phonesInWord in wordsList)
                {
                    resultCount = SearchWord(phonesInWord, returnCountOnly,
                                             (phoneIndexOfMatch, numberOfPhonesInMatch) =>
                                             ResultCache.Add(wentry, phonesInWord, phoneIndexOfMatch, numberOfPhonesInMatch, true));
                }
            }

            return(true);
        }
예제 #5
0
        public TValue GetValue()
        {
            var result = new ResultCache();

            AsyncGet(result);
            return(result.Value);
        }
예제 #6
0
        public static void StringResultCreation(string x)
        {
            var expected = Result.Ok(x);
            var cache    = new ResultCache(1);
            var actual   = (Result <string>)cache.RetrieveOrCacheOk(typeof(string), x);

            Assert.True(ResultEqual(expected, actual));
        }
예제 #7
0
        public static void IntListResultCreation(List <int> x)
        {
            var expected = Result.Ok(x);
            var cache    = new ResultCache(1);
            var actual   = (Result <List <int> >)cache.RetrieveOrCacheOk(typeof(List <int>), x);

            Assert.True(ResultEqual(expected, actual));
        }
예제 #8
0
        public static void IntListResultErrorCreation(IEnumerable <Error> errors, ResultClass resultClass)
        {
            var expected = Result.WithErrors <List <int> >(errors, resultClass);
            var cache    = new ResultCache(1);
            var actual   = (Result <List <int> >)cache.RetrieveOrCacheWithErrors(typeof(List <int>), errors, resultClass);

            Assert.True(ResultEqual(expected, actual));
        }
예제 #9
0
        public async Task ResultFailReturnsDefaultObject()
        {
            var mock   = new MockDataRetriever();
            var cache  = new ResultCache <string>(Key, mock.GetFailData, GetCache());
            var result = await cache.Get();

            Assert.Null(result);
        }
예제 #10
0
        public static void IntResultCreation(int x)
        {
            var expected = Result.Ok(x);
            var cache    = new ResultCache(1);
            var actual   = (Result <int>)cache.RetrieveOrCacheOk(typeof(int), x);

            Assert.Equal(expected, actual);
        }
예제 #11
0
        public async Task DataIsRetrievedOnceOnFirstTimeUse()
        {
            var mock       = new MockDataRetriever();
            var cache      = new ResultCache <string>(Key, mock.GetData, GetCache());
            var cachedData = await cache.Get();

            Assert.Equal(1, mock.DataRetrievalCount);
            Assert.Equal("this is the data", cachedData);
        }
예제 #12
0
        static public ResultCache Get()
        {
            if (cache == null)
            {
                cache = new ResultCache();
            }

            return(cache);
        }
예제 #13
0
 public static HashSet <string> GetFiles(
     ResultCache cache,
     string searchableDirectory,
     IEnumerable <IPattern> includePaths,
     IEnumerable <IPattern> excludePaths,
     string basePath = null)
 {
     return(GetFiles(cache, new[] { searchableDirectory }, includePaths, excludePaths, basePath));
 }
예제 #14
0
        public IEnumerable <TItem> Read <TItem>()
        {
            TableIdentity       heading = TableIdentity.FromRecord(this.syncReader);
            ResultState <TItem> state   = ResultCache <TItem> .GetResultState(this.schemas, heading);

            while (this.syncReader.Read())
            {
                yield return(state.Item(this.syncReader));
            }
        }
        public void GetEmptyResultFromCache()
        {
            ResultCache sut = new ResultCache();

            ProcessingResult cachedResultUser1 = sut.Get("testUser1");

            sut.Set("testUser3", new ProcessingResult());
            ProcessingResult cachedResultUser2 = sut.Get("testUser2");

            Assert.Null(cachedResultUser1);
            Assert.Null(cachedResultUser2);
        }
예제 #16
0
        public void PoisonDisposesTheCache()
        {
            var mock  = new MockDataRetriever();
            var cache = new ResultCache <string>(Key, mock.GetData, GetCache());

            cache.Get();

            Assert.Equal(1, mock.DataRetrievalCount);
            cache.Poison();
            cache.Get();
            Assert.Equal(2, mock.DataRetrievalCount);
        }
예제 #17
0
        public async Task WhenCacheIsEmptyItReRetrievesTheData()
        {
            var mock            = new MockDataRetriever();
            var underlyingCache = GetCache();
            var cache           = new ResultCache <string>(Key, mock.GetData, underlyingCache);

            underlyingCache.Remove(Key);

            var cachedData = await cache.Get();

            Assert.Equal(1, mock.DataRetrievalCount);
            Assert.Equal("this is the data", cachedData);
        }
        private ServiceCallSite TryCreateOpenGeneric(ServiceDescriptor descriptor, Type serviceType, CallSiteChain callSiteChain, int slot)
        {
            if (serviceType.IsConstructedGenericType &&
                serviceType.GetGenericTypeDefinition() == descriptor.ServiceType)
            {
                Debug.Assert(descriptor.ImplementationType != null, "descriptor.ImplementationType != null");
                var lifetime   = new ResultCache(descriptor.Lifetime, serviceType, slot);
                var closedType = descriptor.ImplementationType.MakeGenericType(serviceType.GenericTypeArguments);
                return(CreateConstructorCallSite(lifetime, serviceType, closedType, callSiteChain));
            }

            return(null);
        }
        public void GetResultFromCacheAfterInitialAdd()
        {
            ResultCache      sut         = new ResultCache();
            ProcessingResult resultUser1 = new ProcessingResult();
            ProcessingResult resultUser2 = new ProcessingResult();

            sut.Set("testUser1", resultUser1);
            sut.Set("testUser2", resultUser2);
            ProcessingResult cachedResultUser1 = sut.Get("testUser1");
            ProcessingResult cachedResultUser2 = sut.Get("testUser2");

            Assert.Equal(resultUser1, cachedResultUser1);
            Assert.Equal(resultUser2, cachedResultUser2);
        }
예제 #20
0
        public async IAsyncEnumerable <TItem> ReadAsync <TItem>([EnumeratorCancellation] CancellationToken cancellationToken = default)
        {
            if (this.asyncReader == null)
            {
                throw new QueryException("Async not available. To use async operations, please supply a connection factory returning a DbConnection instance.");
            }

            TableIdentity       heading = TableIdentity.FromRecord(this.asyncReader);
            ResultState <TItem> state   = ResultCache <TItem> .GetResultState(this.schemas, heading);

            while (await this.asyncReader.ReadAsync(cancellationToken).ConfigureAwait(false))
            {
                yield return(state.Item(this.asyncReader));
            }
        }
예제 #21
0
파일: Node.cs 프로젝트: mikeblakeuk/MNP
        private void GetResultFromCache(IPAddress source, string tag)
        {
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }

            if (String.IsNullOrEmpty(tag))
            {
                throw new ArgumentNullException("tag");
            }

            if (ResultCache.Contains(tag))
            {
                SendToNode(source, ClientResultMessageSerialiser.Serialise(ResultCache[tag]));
            }
        }
예제 #22
0
        public async Task CachedDataIsRetrievedOnSubsequentUse()
        {
            var mock    = new MockDataRetriever();
            var cache   = new ResultCache <string>(Key, mock.GetData, GetCache());
            var result1 = await cache.Get();

            var result2 = await cache.Get();

            var result3 = await cache.Get();

            var result4 = await cache.Get();

            var result5 = await cache.Get();

            Assert.Equal(1, mock.DataRetrievalCount);
            Assert.True(new[] { result1, result2, result3, result4, result5 }.All(o => o.Equals("this is the data")));
        }
        public void GetResultFromCacheAfterRewrite()
        {
            ResultCache sut = new ResultCache();

            ProcessingResult result1 = new ProcessingResult();

            sut.Set("testUser", result1);
            ProcessingResult cachedResult1 = sut.Get("testUser");

            Assert.Equal(result1, cachedResult1);

            ProcessingResult Result = new ProcessingResult();

            sut.Set("testUser", Result);
            ProcessingResult cachedResult2 = sut.Get("testUser");

            Assert.Equal(Result, cachedResult2);
        }
예제 #24
0
        public static bool Create <T>(T albianObject)
            where T : class, IAlbianObject
        {
            if (null == albianObject)
            {
                throw new ArgumentNullException("albianObject");
            }
            TaskBuilder builder           = new TaskBuilder();
            ITask       task              = builder.BuildCreateTask(albianObject);
            ITransactionClusterScope tran = new TransactionClusterScope();
            bool isSuccess = tran.Execute(task);

            if (!isSuccess)
            {
                return(isSuccess);
            }
            ResultCache.CachingObject(albianObject);
            return(isSuccess);
        }
예제 #25
0
 private static IList <T> DoLoadObjects <T>(IDbCommand cmd)
     where T : class, IAlbianObject, new()
 {
     try
     {
         IQueryCluster query   = new QueryCluster();
         IList <T>     targets = query.QueryObjects <T>(cmd);
         ResultCache.CachingObjects(cmd, targets);
         return(targets);
     }
     catch (Exception exc)
     {
         if (null != Logger)
         {
             Logger.ErrorFormat("Find Object is error..info:{0}.", exc.Message);
         }
         throw;
     }
 }
예제 #26
0
        public async Task SeperateInstancesWithSameKey()
        {
            var mock    = new MockDataRetriever();
            var cache   = new ResultCache <string>(Key, mock.GetData, GetCache());
            var cache2  = new ResultCache <string>(Key, mock.GetData, GetCache());
            var result1 = await cache.Get();

            var result2 = await cache.Get();

            var result3 = await cache.Get();

            var result4 = await cache2.Get();

            var result5 = await cache2.Get();

            var result6 = await cache2.Get();

            Assert.Equal(2, mock.DataRetrievalCount); // we expect 2 because the data will be re-retrieved when newing up the second instance
            Assert.True(new[] { result1, result2, result3, result4, result5, result6 }.All(o => o.Equals("this is the data")));
        }
예제 #27
0
파일: Node.cs 프로젝트: mikeblakeuk/MNP
        internal void AddToCache(bool localOnly, string key, byte[] value)
        {
            // Sanity check everything first.
            if (String.IsNullOrEmpty(key))
            {
                throw new ArgumentException("The key cannot be null", "key");
            }

            if (value == null || value.Length == 0)
            {
                throw new ArgumentException("The entry to the cache cannot be null", "value");
            }

            ClientResultMessage msg = new ClientResultMessage {
                Data = value, Key = key
            };

            // Update
            ResultCache.Write(key, msg, localOnly);
        }
예제 #28
0
        public async Task <Response> Request(Request request)
        {
            // Send request
            var resultReady = new AutoResetEvent(false);

            RequestQueue[request.Id] = resultReady;
            await RpcLayer.SendRequest(request);

            await Task.Run(() => resultReady.WaitOne());

            // Remove lock from queue
            AutoResetEvent removedEvent;

            RequestQueue.TryRemove(request.Id, out removedEvent);
            // Retrieve result
            var      result = ResultCache[request.Id];
            Response dequeuedResponse;

            ResultCache.TryRemove(request.Id, out dequeuedResponse);
            return(result);
        }
예제 #29
0
 private static T DoLoadObject <T>(string routingName, IFilterCondition[] where)
     where T : class, IAlbianObject, new()
 {
     try
     {
         ITaskBuilder  taskBuilder = new TaskBuilder();
         ITask         task        = taskBuilder.BuildQueryTask <T>(routingName, 0, where, null);
         IQueryCluster query       = new QueryCluster();
         T             target      = query.QueryObject <T>(task);
         ResultCache.CachingObject(routingName, where, target);
         return(target);
     }
     catch (Exception exc)
     {
         if (null != Logger)
         {
             Logger.ErrorFormat("load Object is error..info:{0}.", exc.Message);
         }
         throw;
     }
 }
예제 #30
0
        public async Task WhenCacheIsEmptyItReRetrievesTheDataAndCachesIt()
        {
            var mock            = new MockDataRetriever();
            var underlyingCache = GetCache();
            var cache           = new ResultCache <string>(Key, mock.GetData, underlyingCache);

            underlyingCache.Remove(Key);

            var result1 = await cache.Get();

            var result2 = await cache.Get();

            var result3 = await cache.Get();

            var result4 = await cache.Get();

            var result5 = await cache.Get();

            Assert.Equal(1, mock.DataRetrievalCount);
            Assert.True(new[] { result1, result2, result3, result4, result5 }.All(o => o.Equals("this is the data")));
        }
예제 #31
0
        internal Result Execute
            (
            Category category,
            ResultCache left,
            Syntax token,
            ContextBase context,
            Parser.Value right)
        {
            var trace = ObjectId.In(34) && category.HasCode;
            StartMethodDump(trace, category, left, token, context, right);
            try
            {
                var metaFeature = ((IMetaImplementation) Feature).Function;
                if(metaFeature != null)
                    return metaFeature.Result(category, left, context, right);

                BreakExecution();
                var result = Feature.Result(category.Typed, token, context, right);
                Dump(nameof(result), result);
                Dump("ConverterPath.Destination.CheckedReference", ConverterPath.Destination.CheckedReference);
                Dump("ConverterPath.Execute", ConverterPath.Execute(Category.Code));
                BreakExecution();

                var replaceAbsolute = result
                    .ReplaceAbsolute
                    (ConverterPath.Destination.CheckedReference, ConverterPath.Execute);
                Dump(nameof(replaceAbsolute), replaceAbsolute);
                if(trace)
                    Dump(nameof(left), left.Code);
                BreakExecution();

                return ReturnMethodDump(replaceAbsolute.ReplaceArg(left));

            }
            finally
            {
                EndMethodDump();
            }
        }
예제 #32
0
 ReplaceRelRefArg(ResultCache actualArg, Size offset)
     : base(actualArg)
 {
     Offset = offset;
     StopByObjectIds(-9);
 }
        /// <summary>
        /// Creates equifrequency intervals from the sorted array of values from database.
        /// </summary>
        /// <param name="intervals">Requested number of intervals.</param>
        /// <param name="sortedValues">It is assumed that the values from database are of type double, although any type that converts to double will do. The array must be already sorted though.</param>
        /// <returns>An array of dividing points. The first point returned is the right bound of the first value (the left bound can be -INF), the last point returned is the left bound of the last interval (right bound can be INF).</returns>
        /// <remarks>
        /// <para>This method is an optimization algorithm. It heuristically checks many different
        /// combinations of dividing points and computes scoring for every such division.
        /// The scoring function is in fact a least square method and the optimization is searching
        /// for point of minimum error. See more details in other types of documentation.</para>
        /// </remarks>
        public static object[] GenerateIntervals(int intervals, object[] sortedValues)
        {
            if ((sortedValues == null) || (sortedValues.Length == 0))
                throw new ArgumentException("The reference to the array of sorted values is null or contains no elements.", "sortedValues");

            if (intervals < 1)
                throw new ArgumentOutOfRangeException("intervals", intervals, "The number of intervals must be at least 1.");

            // create an array list of values and their counts
            ArrayList dataArray = new ArrayList();
            int i = 0;
            object currentValue = null;
            while (i < sortedValues.Length)
            {
                currentValue = sortedValues[i];
                i++;
                if (currentValue != null)
                    break;
            }
            if (currentValue == null)
                throw new ArgumentException("The array of values contains only null values.");

            int currentCount = 1;
            int totalCount = 1;
            while (i < sortedValues.Length)
            {
                if (sortedValues[i] != null)
                {
                    Debug.Assert(((IComparable) currentValue).CompareTo((IComparable) sortedValues[i]) <= 0);
                    if (currentValue.Equals(sortedValues[i]))
                    {
                        currentCount++;
                    }
                    else
                    {
                        dataArray.Add(new Data(currentValue, currentCount));
                        currentValue = sortedValues[i];
                        currentCount = 1;
                    }
                    totalCount++;
                }
                i++;
            }
            dataArray.Add(new Data(currentValue, currentCount));

            // assert that the number of intervals is less than or equal to the total number of different values
            if (dataArray.Count < intervals)
                throw new ArgumentOutOfRangeException("intervals", intervals, "The requested number of intervals is less than the total number of different values.");

            // initialize the cache
            ResultCache cache = new ResultCache(intervals);

            #if PERFCOUNTERS
            recursionCount = 0;
            cacheHit = 0;
            cacheMiss = 0;
            #endif

            // start the recursion
            Result result = FindSplit(dataArray, new Interval(0, dataArray.Count), intervals, (float) totalCount / (float) intervals, cache);

            #if PERFCOUNTERS
            Trace.WriteLine("Equifrequency intervals performance:");
            Trace.WriteLine(String.Format("total {0}", totalCount));
            Trace.WriteLine(String.Format("different values {0}", dataArray.Count));
            Trace.WriteLine(String.Format("intervals {0}", intervals));
            Trace.WriteLine(String.Format("recursion {0}", recursionCount));
            Trace.WriteLine(String.Format("cache hits {0}", cacheHit));
            Trace.WriteLine(String.Format("cache misses {0}", cacheMiss));
            Trace.WriteLine(String.Format("result error {0}", result.Cost));
            Trace.WriteLine(String.Empty);
            #endif

            // get the split points
            object[] resultObjects = new object[intervals - 1];
            for (i = 0; i < intervals - 1; i++)
            {
                resultObjects[i] = ((Data) dataArray[((Interval) result.Intervals[i]).Right]).Value;
            }
            return resultObjects;
        }
        private static Result FindSplit(ArrayList dataArray, Interval bounds, int intervals, float optimum, ResultCache cache)
        {
            #if PERFCOUNTERS
            recursionCount++;
            #endif

            #if SCOREGRAPH
            bool topLevel = (bounds.Left == 0) && (bounds.Right == dataArray.Count);
            #endif

            // check if there is enough split points
            Debug.Assert(bounds.Right - bounds.Left >= intervals);

            // test the end of recursion (no splitting)
            if (intervals == 1)
            {
                Result result = new Result();
                result.Intervals.Add(bounds);
                int count = 0;
                for (int i = bounds.Left; i < bounds.Right; i++)
                    count += ((Data) dataArray[i]).Count;
                result.Cost = ResultPenalty(count, optimum);
                return result;
            }

            // test the end of recursion (exact splitting, no choice)
            if (intervals == bounds.Right - bounds.Left)
            {
                Result result = new Result();
                result.Cost = 0.0f;
                for (int i = bounds.Left; i < bounds.Right; i++)
                {
                    result.Intervals.Add(new Interval(i, i + 1));
                    result.Cost += ResultPenalty(((Data) dataArray[i]).Count, optimum);
                }
                return result;
            }

            // cache lookup
            {
                Result result = cache.GetResult(intervals, bounds);
                if (result != null)
                    return result;
            }

            // count objects that must be in the left part
            int leftIntervals = intervals / 2;
            int leftSum = 0;
            for (int i = 0; i < leftIntervals; i++)
                leftSum += ((Data) dataArray[bounds.Left + i]).Count;

            // add some more intervals until optimal point is reached
            int bestSplit;
            int leftOptimalSum = (int) Math.Round(optimum * leftIntervals);
            for (bestSplit = bounds.Left + leftIntervals; bestSplit < bounds.Right - (intervals - leftIntervals); bestSplit++)
            {
                if (leftSum + ((Data) dataArray[bestSplit]).Count > leftOptimalSum)
                    break;
                leftSum += ((Data) dataArray[bestSplit]).Count;
            }

            // start testing these split points (spreading to left and right)
            int leftSplit = bestSplit;
            int rightSplit = bestSplit + 1;
            bool leftStop = false;  // there's always at least one solution
            bool rightStop = (rightSplit > bounds.Right - (intervals - leftIntervals));  // go right only if there is another possible split point

            // spread to both sides and search for better solutions
            Result bestResult = new Result(), leftTmpResult, rightTmpResult;
            bestResult.Cost = initPenalty;
            float leftLastScore = initPenalty, rightLastScore = initPenalty;
            int leftGrowCount = 0, rightGrowCount = 0;
            while (!leftStop || !rightStop)
            {
                if (!leftStop)
                {
                    // find solution for left and right part
                    leftTmpResult = FindSplit(dataArray, new Interval(bounds.Left, leftSplit), leftIntervals, optimum, cache);
                    rightTmpResult = FindSplit(dataArray, new Interval(leftSplit, bounds.Right), intervals - leftIntervals, optimum, cache);

                    // sum the costs of partial results
                    float sum = leftTmpResult.Cost + rightTmpResult.Cost;

            #if SCOREGRAPH
                    if (topLevel)
                    {
                        // top level in the recursion
                        Trace.WriteLine(String.Format("{0};{1}", leftSplit, sum));
                    }
            #endif

                    // first solution is propagated to the right side
                    if (rightLastScore == initPenalty)
                    {
                        // save to right last value
                        rightLastScore = sum;
                    }

                    // compare this result to what we have so far
                    if (sum < bestResult.Cost)
                    {
                        // merge two partial solution to one
                        bestResult.Merge(leftTmpResult, rightTmpResult);

                        // absolute stop criterium (perfect result)
                        if (sum == 0.0f)
                            break;
                    }

            #if SCOREGRAPH
                    if (!topLevel)
                    {
            #endif

                        // check stop criterium (result penalty is too big)
                        if (sum > stopLimit * bestResult.Cost)
                        {
                            // stop spreading to the left
                            leftStop = true;
                        }

                        // check stop criterium (result penalty is constantly growing, so there is
                        // probably no hope of getting better result than we have...)
                        if (sum < leftLastScore)
                        {
                            // not growing, reset the counter
                            leftGrowCount = 0;
                        }
                        else
                        {
                            // growing, increase
                            leftGrowCount++;
                            if (leftGrowCount == growLimit)
                                leftStop = true;
                        }
                        leftLastScore = sum;

            #if SCOREGRAPH
                    }
            #endif

                    // check if there is possibility to spread further to the left
                    if (leftSplit <= bounds.Left + leftIntervals)
                    {
                        // stop testing spreading to the left
                        leftStop = true;
                    }
                    else
                    {
                        // shift the left split to the next position
                        leftSplit--;
                    }
                }

                if (!rightStop)
                {
                    // find solution for left and right part
                    leftTmpResult = FindSplit(dataArray, new Interval(bounds.Left, rightSplit), leftIntervals, optimum, cache);
                    rightTmpResult = FindSplit(dataArray, new Interval(rightSplit, bounds.Right), intervals - leftIntervals, optimum, cache);

                    // sum the costs of partial results
                    float sum = leftTmpResult.Cost + rightTmpResult.Cost;

            #if SCOREGRAPH
                    if (topLevel)
                    {
                        // top level in the recursion
                        Trace.WriteLine(String.Format("{0};{1}", rightSplit, sum));
                    }
            #endif

                    // compare this result to what we have so far
                    if (sum < bestResult.Cost)
                    {
                        // merge two partial solution to one
                        bestResult.Merge(leftTmpResult, rightTmpResult);
                    }

            #if SCOREGRAPH
                    if (!topLevel)
                    {
            #endif

                        // check stop criterium (result penalty is too big)
                        if (sum > stopLimit * bestResult.Cost)
                        {
                            // stop testing spreading to the right
                            rightStop = true;
                        }

                        // check stop criterium (result penalty is constantly growing, so there is
                        // probably no hope of getting better result than we have...)
                        if (sum < rightLastScore)
                        {
                            // not growing, reset the counter
                            rightGrowCount = 0;
                        }
                        else
                        {
                            // growing, increase
                            rightGrowCount++;
                            if (rightGrowCount == growLimit)
                                rightStop = true;
                        }
                        rightLastScore = sum;

            #if SCOREGRAPH
                    }
            #endif

                    // check if there is possibility to spread further to the right
                    if (rightSplit >= bounds.Right - (intervals - leftIntervals))
                    {
                        // stop testing spreading to the right
                        rightStop = true;
                    }
                    else
                    {
                        // shift the right split to the next position
                        rightSplit++;
                    }
                }
            }

            // check the solution
            Debug.Assert(bestResult.Cost < initPenalty);

            // add the best result to cache
            cache.SetResult(intervals, bounds, bestResult);

            // ...and return it
            return bestResult;
        }
        /// <summary>
        /// Generates the intervals.
        /// </summary>
        /// <param name="intervals">The count of required intervals.</param>
        /// <param name="dataArray">The data array.</param>
        /// <returns>Split points.</returns>
        public static object[] GenerateIntervals(int intervals, ArrayList dataArray)
        {
            // assert that the number of intervals is less than or equal to the total number of different values
            if (dataArray.Count < intervals)
                throw new ArgumentOutOfRangeException("intervals", intervals, "The requested number of intervals is less than the total number of different values.");

            // initialize the cache
            ResultCache cache = new ResultCache(intervals);

            // start the recursion
            Result result = FindSplit(dataArray, new Interval(0, dataArray.Count), intervals, (float)dataArray.Count / (float)intervals, cache);

            // get the split points
            object[] resultObjects = new object[intervals - 1];
            for (int i = 0; i < intervals - 1; i++)
            {
                resultObjects[i] = ((Data)dataArray[((Interval)result.Intervals[i]).Right]).Value;
            }
            return resultObjects;
        }
예제 #36
0
 public ReplaceAbsoluteArg(ResultCache actualArg)
     : base(actualArg) { }
예제 #37
0
 Result IMeta.Result
     (Category category, ResultCache left, ContextBase contextBase, Value right)
 {
     NotImplementedMethod(contextBase, left, category, right);
     return null;
 }
예제 #38
0
 internal ReplaceRelRefArg(ResultCache actualArg)
     : this(actualArg, Size.Create(0)) {}
예제 #39
0
 internal ReplaceArg(ResultCache actualArg)
     : base(_nextObjectId++)
 {
     Tracer.Assert(actualArg != null, () => "actualArg != null");
     ActualArg = actualArg;
 }