source: trunk/CrypPlugins/QuadraticSieve/QuadraticSieve.cs @ 1593

Last change on this file since 1593 was 1593, checked in by Sven Rech, 12 years ago

possibility to give out measures in quadratic sieve plugin to show with gnuplot

File size: 31.7 KB
Line 
1/*                             
2   Copyright 2009 Team CrypTool (Sven Rech,Dennis Nolte,Raoul Falk,Nils Kopal), Uni Duisburg-Essen
3
4   Licensed under the Apache License, Version 2.0 (the "License");
5   you may not use this file except in compliance with the License.
6   You may obtain a copy of the License at
7
8       http://www.apache.org/licenses/LICENSE-2.0
9
10   Unless required by applicable law or agreed to in writing, software
11   distributed under the License is distributed on an "AS IS" BASIS,
12   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   See the License for the specific language governing permissions and
14   limitations under the License.
15*/
16
17using System;
18using System.Collections;
19using System.Linq;
20using System.Text;
21using Cryptool.PluginBase;
22using Cryptool.PluginBase.IO;
23using Cryptool.PluginBase.Miscellaneous;
24using System.ComponentModel;
25using System.Threading;
26using System.IO;
27using System.Windows.Controls;
28using System.Windows.Threading;
29using System.Windows;
30using System.Reflection;
31using System.Numerics;
32using System.Collections.Generic;
33using System.Diagnostics;
34using Cryptool.P2P;
35
36namespace Cryptool.Plugins.QuadraticSieve
37{
38    /// <summary>
39    /// This class wraps the msieve algorithm in version 1.42 which you can find at http://www.boo.net/~jasonp/qs.html
40    /// It also extends the msieve functionality to multi threading
41    /// Many thanks to the author of msieve "jasonp_sf"
42    ///
43    /// For further information on quadratic sieve or msieve please have a look at the above mentioned URL
44    /// </summary>
45    [Author("Sven Rech", "rech@cryptool.org", "Uni Duisburg-Essen", "http://www.uni-due.de")]
46    [PluginInfo(false, "Quadratic Sieve", "Sieving Primes", "QuadraticSieve/DetailedDescription/Description.xaml", "QuadraticSieve/iconqs.png")]
47    class QuadraticSieve : DependencyObject, IThroughput
48    {
49        #region private variables
50
51        private readonly string directoryName;
52        private QuadraticSieveSettings settings;
53        private BigInteger inputNumber;
54        private BigInteger[] outputFactors;
55        private bool running;
56        private Queue yieldqueue;
57        private AutoResetEvent yieldEvent = new AutoResetEvent(false);
58        private IntPtr obj = IntPtr.Zero;
59        private volatile int threadcount = 0;
60        private ArrayList conf_list;
61        private bool userStopped = false;
62        private FactorManager factorManager;
63        private PeerToPeer peerToPeer;
64        private bool usePeer2Peer;
65        private bool useGnuplot = true;
66        private StreamWriter gnuplotFile;
67
68        private static Assembly msieveDLL = null;
69        private static Type msieve = null;
70        private static bool alreadyInUse = false;
71        private static Mutex alreadyInUseMutex = new Mutex();
72
73        #endregion
74
75        #region events
76
77        public event StatusChangedEventHandler OnPluginStatusChanged;
78        public event GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
79        public event PluginProgressChangedEventHandler OnPluginProgressChanged;
80        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
81        public event PluginProgressChangedEventHandler OnPluginProcessChanged;       
82
83        #endregion
84
85        #region public
86
87        /// <summary>
88        /// Constructor
89        ///
90        /// constructs a new QuadraticSieve plugin
91        /// </summary>
92        public QuadraticSieve()
93        {
94            Settings = new QuadraticSieveSettings();
95
96            directoryName = Path.Combine(DirectoryHelper.DirectoryLocalTemp, "msieve");
97            if (!Directory.Exists(directoryName)) Directory.CreateDirectory(directoryName);
98
99            QuickWatchPresentation = new QuadraticSievePresentation();
100
101            peerToPeer = new PeerToPeer(quadraticSieveQuickWatchPresentation, yieldEvent);
102            peerToPeer.P2PWarning += new PeerToPeer.P2PWarningHandler(peerToPeer_P2PWarning);
103           
104            quadraticSieveQuickWatchPresentation.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
105            {
106                quadraticSieveQuickWatchPresentation.peer2peerExpander.Visibility = settings.UsePeer2Peer ? Visibility.Visible : Visibility.Collapsed;
107                quadraticSieveQuickWatchPresentation.timeLeft.Text = "?";
108                quadraticSieveQuickWatchPresentation.endTime.Text = "?";
109                quadraticSieveQuickWatchPresentation.logging.Text = "Currently not sieving.";
110            }
111            , null);
112        }
113
114        /// <summary>
115        /// Getter / Setter for the settings of this plugin
116        /// </summary>
117        public Cryptool.PluginBase.ISettings Settings
118        {
119            get { return this.settings; }
120            set
121            {
122                this.settings = (QuadraticSieveSettings)value;
123                this.settings.PropertyChanged += new PropertyChangedEventHandler(settings_PropertyChanged);
124            }
125        }
126
127        private void settings_PropertyChanged(object sender, PropertyChangedEventArgs e)
128        {
129            if (e.PropertyName == "UsePeer2Peer")
130            {
131                if (quadraticSieveQuickWatchPresentation != null)
132                {
133                    quadraticSieveQuickWatchPresentation.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
134                    {
135                        quadraticSieveQuickWatchPresentation.peer2peerExpander.Visibility = settings.UsePeer2Peer ? Visibility.Visible : Visibility.Collapsed;
136                    }, null);
137                }
138            }
139        }
140
141        /// <summary>
142        /// Called by the environment before executing this plugin
143        /// </summary>
144        public void PreExecution()
145        { 
146        }
147       
148        /// <summary>
149        /// Called by the environment to execute this plugin
150        /// </summary>
151        public void Execute()
152        {
153            if (checkInUse())
154                return;
155
156            usePeer2Peer = settings.UsePeer2Peer;
157            if (usePeer2Peer && !P2PManager.Instance.IsP2PConnected())
158            {
159                GuiLogMessage("No connection to Peer2Peer network. Sieving locally now!", NotificationLevel.Warning);
160                usePeer2Peer = false;
161            }
162            if (usePeer2Peer && settings.Channel.Trim() == "")
163            {
164                GuiLogMessage("No channel for Peer2Peer network specified. Sieving locally now!", NotificationLevel.Warning);
165                usePeer2Peer = false;
166            }
167            if (usePeer2Peer)
168            {
169                peerToPeer.SetChannel(settings.Channel);
170                peerToPeer.SetNumber(InputNumber);
171            }
172
173            if (useGnuplot)
174                gnuplotFile = new StreamWriter(Path.Combine(directoryName, "gnuplot.dat"), false);
175                       
176            userStopped = false;
177
178            if (InputNumber != 0)
179            {
180                if (InputNumber.ToString().Length >= 275)
181                {
182                    GuiLogMessage("Input too big.", NotificationLevel.Error);
183                    return;
184                }
185
186                String timeLeft_message = "?";
187                String endtime_message = "?";
188                String logging_message = "Starting quadratic sieve, please wait!";
189
190                GuiLogMessage(logging_message, NotificationLevel.Info);
191                quadraticSieveQuickWatchPresentation.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
192                {
193                    quadraticSieveQuickWatchPresentation.logging.Text = logging_message;
194                    quadraticSieveQuickWatchPresentation.endTime.Text = endtime_message;
195                    quadraticSieveQuickWatchPresentation.timeLeft.Text = timeLeft_message;
196                    quadraticSieveQuickWatchPresentation.factorList.Items.Clear();
197                    quadraticSieveQuickWatchPresentation.factorInfo.Content = "Searching trivial factors!";
198                    if (usePeer2Peer)
199                        quadraticSieveQuickWatchPresentation.relationsInfo.Content = "";
200                    else
201                        quadraticSieveQuickWatchPresentation.relationsInfo.Content = "Only local sieving!";
202                }
203                , null);   
204
205                DateTime start_time = DateTime.Now;
206
207                initMsieveDLL();
208                factorManager = new FactorManager(msieve.GetMethod("getPrimeFactors"), msieve.GetMethod("getCompositeFactors"), InputNumber);
209                factorManager.FactorsChanged += this.FactorsChanged;
210
211                //Now factorize:               
212                try
213                {
214                    string file = Path.Combine(directoryName, "" + InputNumber + ".dat");
215                    if (settings.DeleteCache && File.Exists(file))
216                        File.Delete(file);
217                    MethodInfo start = msieve.GetMethod("start");
218                    start.Invoke(null, new object[] { InputNumber.ToString(), file });
219                    obj = IntPtr.Zero;
220                }
221                catch (Exception ex)
222                {
223                    GuiLogMessage("Error using msieve. " + ex.Message, NotificationLevel.Error);
224                    stopThreads();
225                    return;
226                }
227
228                if (!userStopped)
229                {
230                    timeLeft_message = "0 seconds left";
231                    endtime_message = "" + (DateTime.Now);
232                    logging_message = "Sieving finished in " + (DateTime.Now - start_time) + "!";
233
234                    GuiLogMessage(logging_message, NotificationLevel.Info);
235                    quadraticSieveQuickWatchPresentation.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
236                    {
237                        quadraticSieveQuickWatchPresentation.logging.Text = logging_message;
238                        quadraticSieveQuickWatchPresentation.endTime.Text = endtime_message;
239                        quadraticSieveQuickWatchPresentation.timeLeft.Text = timeLeft_message;
240                        quadraticSieveQuickWatchPresentation.factorInfo.Content = "";
241                    }
242                    , null);
243
244                    Debug.Assert(factorManager.CalculateNumber() == InputNumber);
245                    OutputFactors = factorManager.getPrimeFactors();
246                }
247                else
248                {
249                    timeLeft_message = "0 sec left";
250                    endtime_message = "Stopped";
251                    logging_message = "Stopped by user!";
252
253                    GuiLogMessage(logging_message, NotificationLevel.Info);
254                    quadraticSieveQuickWatchPresentation.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
255                    {
256                        quadraticSieveQuickWatchPresentation.logging.Text = logging_message;
257                        quadraticSieveQuickWatchPresentation.endTime.Text = endtime_message;
258                        quadraticSieveQuickWatchPresentation.timeLeft.Text = timeLeft_message;
259                        quadraticSieveQuickWatchPresentation.factorInfo.Content = "";
260                    }
261                    , null);
262                }
263                   
264                ProgressChanged(1, 1);
265               
266            }
267            if (useGnuplot)
268                gnuplotFile.Close();
269
270            alreadyInUse = false;
271        }
272
273        private bool checkInUse()
274        {
275            try
276            {
277                alreadyInUseMutex.WaitOne();
278                if (alreadyInUse)
279                {
280                    GuiLogMessage("QuadraticSieve plugin is only allowed to execute ones at a time due to technical restrictions.", NotificationLevel.Error);
281                    return true;
282                }
283                else
284                {
285                    alreadyInUse = true;
286                    return false;
287                }
288            }
289            finally
290            {
291                alreadyInUseMutex.ReleaseMutex();
292            }
293        }
294       
295        /// <summary>
296        /// Called by the environment after execution
297        /// </summary>
298        public void PostExecution()
299        {
300        }
301
302        /// <summary>
303        /// Called by the environment to pause execution
304        /// </summary>
305        public void Pause()
306        {
307        }
308
309        /// <summary>
310        /// Called by the environment to stop execution
311        /// </summary>
312        public void Stop()
313        {
314            this.userStopped = true;
315            if (obj != IntPtr.Zero)
316            {
317                stopThreads();
318                MethodInfo stop = msieve.GetMethod("stop");
319                stop.Invoke(null, new object[] { obj });
320            }
321
322        }
323
324        /// <summary>
325        /// Called by the environment to initialize this plugin
326        /// </summary>
327        public void Initialize()
328        {
329            settings.Initialize();
330        }
331
332        /// <summary>
333        /// Called by the environment to dispose this plugin
334        /// </summary>
335        public void Dispose()
336        {
337        }
338
339        /// <summary>
340        /// Getter / Setter for the input number which should be factorized
341        /// </summary>
342        [PropertyInfo(Direction.InputData, "Number input", "Enter the number you want to factorize", "", DisplayLevel.Beginner)]
343        public BigInteger InputNumber
344        {
345            get
346            {
347                return inputNumber;
348            }
349            set
350            {
351                this.inputNumber = value;
352                OnPropertyChanged("InputNumber");
353            }
354        }
355
356        /// <summary>
357        /// Getter / Setter for the factors calculated by msieve
358        /// </summary>
359        [PropertyInfo(Direction.OutputData, "Factors output", "Your factors will be sent here", "", DisplayLevel.Beginner)]
360        public BigInteger[] OutputFactors
361        {
362            get
363            {
364                return outputFactors;
365            }
366            set
367            {
368                this.outputFactors = value;
369                OnPropertyChanged("OutputFactors");
370            }
371        }
372       
373        /// <summary>
374        /// Called when a property of this plugin changes
375        /// </summary>
376        /// <param name="name">name</param>
377        public void OnPropertyChanged(string name)
378        {
379            EventsHelper.PropertyChanged(PropertyChanged, this, new PropertyChangedEventArgs(name));
380        }
381
382        /// <summary>
383        /// Getter / Setter for the presentation of this plugin
384        /// </summary>
385        public UserControl Presentation { get; private set; }
386
387        /// <summary>
388        /// Getter / Setter for the QuickWatchPresentation of this plugin
389        /// </summary>
390        public UserControl QuickWatchPresentation
391        {
392            get;
393            private set;
394        }
395
396        #endregion
397
398        #region private
399
400        /// <summary>
401        /// calculate a String which shows the timespan
402        ///
403        /// example
404        ///
405        ///     4 days
406        /// or
407        ///     2 minutes
408        /// </summary>
409        /// <param name="ts"></param>
410        /// <returns></returns>
411        private String showTimeSpan(TimeSpan ts)
412        {
413            String res = "";
414            if (ts.Days != 0)
415                res = ts.Days + " days ";
416            if (ts.Hours != 0 || res.Length != 0)
417                res += ts.Hours + " hours ";
418            if (ts.Minutes != 0)
419                res += ts.Minutes + " minutes";
420            if (res.Length == 0)
421                res += ts.Seconds + " seconds";
422            return res;
423        }
424
425        /// <summary>
426        /// Callback method to prepare sieving
427        /// Called by msieve
428        ///
429        /// </summary>
430        /// <param name="conf">pointer to configuration</param>
431        /// <param name="update">number of relations found</param>
432        /// <param name="core_sieve_fcn">pointer to internal sieve function of msieve</param>
433        private void prepareSieving(IntPtr conf, int update, IntPtr core_sieve_fcn, int max_relations)
434        {
435            int threads = Math.Min(settings.CoresUsed, Environment.ProcessorCount-1);
436            MethodInfo getObjFromConf = msieve.GetMethod("getObjFromConf");
437            this.obj = (IntPtr)getObjFromConf.Invoke(null, new object[] { conf });           
438            yieldqueue = Queue.Synchronized(new Queue());
439            conf_list = new ArrayList();
440
441            String message = "Start sieving using " + (threads + 1) + " cores!";
442            GuiLogMessage(message, NotificationLevel.Info);
443            quadraticSieveQuickWatchPresentation.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
444            {
445                quadraticSieveQuickWatchPresentation.logging.Text = message;
446                if (usePeer2Peer)
447                    quadraticSieveQuickWatchPresentation.relationsInfo.Content = "";
448            }
449            , null);         
450
451            ProgressChanged(0.1, 1.0);
452
453            running = true;
454            //start helper threads:
455            for (int i = 0; i < threads+1; i++)
456            {
457                MethodInfo cloneSieveConf = msieve.GetMethod("cloneSieveConf");
458                IntPtr clone = (IntPtr)cloneSieveConf.Invoke(null, new object[] { conf });               
459                conf_list.Add(clone);
460                WaitCallback worker = new WaitCallback(MSieveJob);
461                ThreadPool.QueueUserWorkItem(worker, new object[] { clone, update, core_sieve_fcn, yieldqueue });
462            }
463
464            //manage the yields of the other threads:
465            manageYields(conf, max_relations);  //this method returns as soon as there are enough relations found
466            if (userStopped)
467                return;
468
469            //sieving is finished now, so give some informations and stop threads:
470            ProgressChanged(0.9, 1.0);
471            GuiLogMessage("Sieving finished", NotificationLevel.Info);
472            quadraticSieveQuickWatchPresentation.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
473            {
474                quadraticSieveQuickWatchPresentation.factorInfo.Content = "Found enough relations! Please wait...";
475            }, null);
476           
477            stopThreads();
478            if (yieldqueue != null)
479                yieldqueue.Clear();
480        }
481
482        /// <summary>
483        /// Manages the whole yields that are created during the sieving process by the other threads (and other peers).
484        /// Returns true, if enough relations have been found.
485        /// </summary>
486        private void manageYields(IntPtr conf, int max_relations)
487        {
488            MethodInfo serializeYield = msieve.GetMethod("serializeYield");
489            MethodInfo deserializeYield = msieve.GetMethod("deserializeYield");
490            MethodInfo getNumRelations = msieve.GetMethod("getNumRelations");
491            int num_relations = (int)getNumRelations.Invoke(null, new object[] { conf });
492            int start_relations = num_relations;
493            DateTime start_sieving_time = DateTime.Now;
494            MethodInfo saveYield = msieve.GetMethod("saveYield");
495
496            while (num_relations < max_relations)
497            {
498                ProgressChanged((double)num_relations / max_relations * 0.8 + 0.1, 1.0);
499               
500                yieldEvent.WaitOne();               //wait until queue is not empty
501                if (userStopped)
502                    return;
503
504                while (yieldqueue.Count != 0)       //get all the results from the helper threads, and store them
505                {
506                    IntPtr yield = (IntPtr)yieldqueue.Dequeue();                   
507
508                    if (usePeer2Peer)
509                    {
510                        byte[] serializedYield = (byte[])serializeYield.Invoke(null, new object[] { yield });
511                        peerToPeer.Put(serializedYield);
512                    }
513
514                    saveYield.Invoke(null, new object[] { conf, yield });
515                }
516
517                if (usePeer2Peer)
518                {
519                    Queue dhtqueue = peerToPeer.GetLoadedYieldsQueue();
520                    while (dhtqueue.Count != 0)       //get all the loaded results from the DHT, and store them
521                    {
522                        byte[] yield = (byte[])dhtqueue.Dequeue();
523                        IntPtr deserializedYield = (IntPtr)deserializeYield.Invoke(null, new object[] { yield });
524                        saveYield.Invoke(null, new object[] { conf, deserializedYield });
525                    }
526                }
527
528                num_relations = (int)getNumRelations.Invoke(null, new object[] { conf });
529                showProgressPresentation(max_relations, num_relations, start_relations, start_sieving_time);
530
531                if (usePeer2Peer && !peerToPeer.SyncFactorManager(factorManager))   //an other peer already finished sieving
532                {
533                    throw new AlreadySievedException();
534                }
535            }           
536        }
537
538        private void showProgressPresentation(int max_relations, int num_relations, int start_relations, DateTime start_sieving_time)
539        {
540            TimeSpan diff = DateTime.Now - start_sieving_time;
541            double msleft = (diff.TotalMilliseconds / (num_relations - start_relations)) * (max_relations - num_relations);
542            if (msleft > 0 && !double.IsInfinity(msleft))
543            {
544                TimeSpan ts = new TimeSpan(0, 0, 0, 0, (int)msleft);
545                String logging_message = "Found " + num_relations + " of " + max_relations + " relations!";
546                String timeLeft_message = showTimeSpan(ts) + " left";
547                String endtime_message = "" + DateTime.Now.AddMilliseconds((long)msleft);
548
549                GuiLogMessage(logging_message + " " + timeLeft_message + ".", NotificationLevel.Debug);
550                quadraticSieveQuickWatchPresentation.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
551                {
552                    quadraticSieveQuickWatchPresentation.logging.Text = logging_message;
553                    quadraticSieveQuickWatchPresentation.timeLeft.Text = timeLeft_message;
554                    quadraticSieveQuickWatchPresentation.endTime.Text = endtime_message;
555                }
556                , null);
557            }
558
559            if (useGnuplot)
560            {
561                double percentage = (double)num_relations / max_relations;
562                double time = (DateTime.Now - start_sieving_time).TotalSeconds;
563                gnuplotFile.WriteLine("" + time + "\t\t" + percentage);
564            }
565        }
566
567        /// <summary>
568        /// This callback method is called by msieve. "list" is the trivial factor list (i.e. it consists of the factors that have been found without
569        /// using the quadratic sieve algorithm).
570        /// The method then factors all the factors that are still composite by using the quadratic sieve.
571        /// </summary>
572        private void getTrivialFactorlist(IntPtr list, IntPtr obj)
573        {
574            //add the trivial factors to the factor list:
575            factorManager.AddFactors(list);
576
577            if (usePeer2Peer)
578                peerToPeer.SyncFactorManager(factorManager);
579           
580            MethodInfo msieve_run_core = msieve.GetMethod("msieve_run_core");
581
582            //Now factorize as often as needed:
583            while (!factorManager.OnlyPrimes())
584            {
585                //get one composite factor, which we want to sieve now:
586                BigInteger compositeFactor = factorManager.GetCompositeFactor();
587                showFactorInformations(compositeFactor);
588                if (usePeer2Peer)
589                    peerToPeer.SetFactor(compositeFactor);
590
591                try
592                {
593                    //now start quadratic sieve on it:               
594                    IntPtr resultList = (IntPtr)msieve_run_core.Invoke(null, new object[2] { obj, compositeFactor.ToString() });
595                    if (userStopped)
596                        return;
597
598                    factorManager.ReplaceCompositeByFactors(compositeFactor, resultList);   //add the result list to factorManager
599
600                    if (usePeer2Peer)
601                        peerToPeer.SyncFactorManager(factorManager);
602                }
603                catch (AlreadySievedException)
604                {
605                    GuiLogMessage("Another peer already finished factorization of composite factor" + compositeFactor + ". Sieving next one...", NotificationLevel.Info);
606                }
607            }
608        }
609
610        private void showFactorInformations(BigInteger compositeFactor)
611        {
612            quadraticSieveQuickWatchPresentation.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
613            {
614                String compRep;
615                if (compositeFactor.ToString().Length < 6)
616                    compRep = compositeFactor.ToString();
617                else
618                    compRep = compositeFactor.ToString().Substring(0, 4) + "...";
619                quadraticSieveQuickWatchPresentation.factorInfo.Content = "Now sieving first composite factor! (" + compRep + ")";
620            }, null);
621        }
622
623        /// <summary>
624        /// Helper Thread for msieve, which sieves for relations:
625        /// </summary>
626        /// <param name="param">params</param>
627        private void MSieveJob(object param)
628        {
629            threadcount++;
630            object[] parameters = (object[])param;
631            IntPtr clone = (IntPtr)parameters[0];
632            int update = (int)parameters[1];
633            IntPtr core_sieve_fcn = (IntPtr)parameters[2];
634            Queue yieldqueue = (Queue)parameters[3];
635
636            while (running)
637            {
638                try
639                {
640                    MethodInfo collectRelations = msieve.GetMethod("collectRelations");
641                    collectRelations.Invoke(null, new object[] { clone, update, core_sieve_fcn });
642                    MethodInfo getYield = msieve.GetMethod("getYield");
643                    IntPtr yield = (IntPtr)getYield.Invoke(null, new object[] { clone });
644
645                    yieldqueue.Enqueue(yield);
646                    yieldEvent.Set();
647                }
648                catch (Exception ex)
649                {
650                    GuiLogMessage("Error using msieve." + ex.Message, NotificationLevel.Error);
651                    threadcount = 0;
652                    return;
653                }               
654            }
655
656            MethodInfo freeSieveConf = msieve.GetMethod("freeSieveConf");
657            freeSieveConf.Invoke(null, new object[] { clone });           
658            threadcount--;
659        }       
660
661        /// <summary>
662        /// Stop all running threads
663        /// </summary>
664        private void stopThreads()
665        {
666            if (conf_list != null)
667            {
668                running = false;
669                if (usePeer2Peer)
670                    peerToPeer.StopLoadStoreThread();
671
672                MethodInfo stop = msieve.GetMethod("stop");
673                MethodInfo getObjFromConf = msieve.GetMethod("getObjFromConf");
674                foreach (IntPtr conf in conf_list)
675                    stop.Invoke(null, new object[] { getObjFromConf.Invoke(null, new object[] { conf }) });
676                GuiLogMessage("Waiting for threads to stop!", NotificationLevel.Debug);
677                while (threadcount > 0)
678                {
679                    Thread.Sleep(0);
680                }
681                GuiLogMessage("Threads stopped!", NotificationLevel.Debug);
682                conf_list.Clear();
683            }
684        }   
685
686        /// <summary>
687        /// Change the progress of this plugin
688        /// </summary>
689        /// <param name="value">value</param>
690        /// <param name="max">max</param>
691        private void ProgressChanged(double value, double max)
692        {
693            EventsHelper.ProgressChanged(OnPluginProgressChanged, this, new PluginProgressEventArgs(value, max));
694        }
695
696        private void FactorsChanged(List<BigInteger> primeFactors, List<BigInteger> compositeFactors)
697        {
698            quadraticSieveQuickWatchPresentation.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
699            {
700                quadraticSieveQuickWatchPresentation.factorList.Items.Clear();
701
702                foreach (BigInteger pf in primeFactors)         
703                    quadraticSieveQuickWatchPresentation.factorList.Items.Add("Prime Factor: " + pf.ToString());           
704
705                foreach (BigInteger cf in compositeFactors)
706                    quadraticSieveQuickWatchPresentation.factorList.Items.Add("Composite Factor: " + cf.ToString());
707            }, null);
708        }
709
710        /// <summary>
711        /// Logs a message to the CrypTool gui
712        /// </summary>
713        /// <param name="p">p</param>
714        /// <param name="notificationLevel">notificationLevel</param>
715        private void GuiLogMessage(string p, NotificationLevel notificationLevel)
716        {
717            EventsHelper.GuiLogMessage(OnGuiLogNotificationOccured, this, new GuiLogEventArgs(p, this, notificationLevel));
718        }
719
720        /// <summary>
721        /// Getter / Setter for the QuickWatchPresentation
722        /// </summary>
723        private QuadraticSievePresentation quadraticSieveQuickWatchPresentation
724        {
725            get { return QuickWatchPresentation as QuadraticSievePresentation; }
726        }
727
728        /// <summary>
729        /// dynamically loads the msieve dll file and sets the callbacks
730        /// </summary>
731        private void initMsieveDLL()
732        {
733            //Load msieve.dll (if necessary):
734            if (msieve == null || msieveDLL == null)
735            {
736                string s = Directory.GetCurrentDirectory();
737                string dllname;
738                if (IntPtr.Size == 4)
739                    dllname = "msieve.dll";
740                else
741                    dllname = "msieve64.dll";
742
743                msieveDLL = Assembly.LoadFile(Directory.GetCurrentDirectory() + "\\AppReferences\\"  + dllname);
744                msieve = msieveDLL.GetType("Msieve.msieve");
745            }
746
747            //init msieve with callbacks:
748            MethodInfo initMsieve = msieve.GetMethod("initMsieve");
749            Object callback_struct = Activator.CreateInstance(msieveDLL.GetType("Msieve.callback_struct"));           
750            FieldInfo prepareSievingField = msieveDLL.GetType("Msieve.callback_struct").GetField("prepareSieving");
751            FieldInfo getTrivialFactorlistField = msieveDLL.GetType("Msieve.callback_struct").GetField("getTrivialFactorlist");           
752            Delegate prepareSievingDel = MulticastDelegate.CreateDelegate(msieveDLL.GetType("Msieve.prepareSievingDelegate"), this, "prepareSieving");
753            Delegate getTrivialFactorlistDel = MulticastDelegate.CreateDelegate(msieveDLL.GetType("Msieve.getTrivialFactorlistDelegate"), this, "getTrivialFactorlist");           
754            prepareSievingField.SetValue(callback_struct, prepareSievingDel);
755            getTrivialFactorlistField.SetValue(callback_struct, getTrivialFactorlistDel);
756            initMsieve.Invoke(null, new object[1] { callback_struct });
757        }
758
759        private void peerToPeer_P2PWarning(string warning)
760        {
761            GuiLogMessage(warning, NotificationLevel.Warning);
762        }
763
764        #endregion
765
766    }
767}
Note: See TracBrowser for help on using the repository browser.