Streamed implementation. Limited input buffer.
[LanSpider.git] / src / Indexer / Program.cs
blobc6c5b285eb4a557950dfcf5626dc71ff1e0c6c30
1 using System;
2 using System.Collections.Generic;
3 using System.Diagnostics;
4 using System.IO;
5 using System.Linq;
6 using System.Runtime.Serialization;
7 using System.Runtime.Serialization.Formatters.Binary;
8 using System.ServiceModel.Channels;
9 using System.Threading;
11 using Indexer.ShareDiscoveryReference;
13 using ShareDiscovery;
15 namespace Indexer
17 internal class Program
19 private static int _sleepTimeout = /*1 minute*/ 60000;
20 private static int _numSharesIndexed = 0;
21 private static int _nDenial = 0;
23 private static void Main( string[] args )
25 ShareDiscoveryServiceClient client = new ShareDiscoveryServiceClient();
26 while ( true )
28 string share = null;
29 Stopwatch startWatch = new Stopwatch();
30 startWatch.Start();
32 string errorMessage = "Got no shares to index.";
33 if ( _numSharesIndexed == 0 )
35 errorMessage += " Share discovery service is probably initializing now.";
38 try
40 share = (new StreamReader(client.GetShareToIndex())).ReadToEnd();
42 catch ( TimeoutException )
44 errorMessage = "Share discovery service timed out.";
47 if ( String.IsNullOrEmpty( share ) )
49 ++_nDenial;
50 double timeout = _sleepTimeout * Math.Sqrt( _nDenial );
51 Console.WriteLine( "[{0}] Error: {1} Sleeping for {2:0.##} seconds.", DateTime.Now, errorMessage,
52 timeout / 1000f );
53 Thread.Sleep( (int) timeout );
54 continue;
56 _nDenial = 0;
58 Console.WriteLine( "[{0}] About to index share {1}.", DateTime.Now, share );
60 try
62 Stopwatch indexWatch = new Stopwatch();
64 indexWatch.Start();
65 TreeNode shareNode = IndexFolder( share );
66 indexWatch.Stop();
68 if ( shareNode != null )
70 if ( startWatch.IsRunning )
72 startWatch.Stop();
73 Console.WriteLine( "[{0}] Share discovery service initialized in {1}", DateTime.Now,
74 startWatch.Elapsed );
77 string[] parts = share.Split( new[] { '\\' }, StringSplitOptions.RemoveEmptyEntries );
79 FileInfo shareInfo = new FileInfo( share );
80 shareNode.CreationTime = shareInfo.CreationTime;
81 shareNode.AccessTime = shareInfo.LastAccessTime;
82 shareNode.ModificationTime = shareInfo.LastWriteTime;
84 TreeNode compNode = new TreeNode();
85 compNode.Name = "//" + parts[ 0 ];
86 compNode.Children = new[] { shareNode };
88 // Count indexed nodes.
89 uint numNodes = 0;
90 Queue<TreeNode> queue = new Queue<TreeNode>();
91 queue.Enqueue( compNode );
93 while ( queue.Count > 0 )
95 TreeNode next = queue.Dequeue();
96 ++numNodes;
97 if ( next.Children != null )
99 foreach ( TreeNode child in next.Children )
101 queue.Enqueue( child );
106 if ( numNodes > 3 )
108 ++_numSharesIndexed;
109 Console.WriteLine( "[{0}] Indexed {1}-th share {2} in {3}. {4} nodes in graph.",
110 DateTime.Now,
111 _numSharesIndexed,
112 share, indexWatch.Elapsed, numNodes );
114 Stream stream = new MemoryStream();
115 IFormatter fmt = new BinaryFormatter();
116 fmt.Serialize( stream, compNode );
117 stream.Seek( 0, SeekOrigin.Begin );
118 client.SaveIndex( stream );
119 stream.Close();
121 Console.WriteLine( "[{0}] Saved share {1}.", DateTime.Now, share );
124 else
126 Console.WriteLine( "[{0}] Wasted {1} on indexing {2}.", DateTime.Now, indexWatch.Elapsed, share );
129 catch ( IOException ex )
131 Console.Error.WriteLine( "[{0}] Error: failed to save {1}: {2}", DateTime.Now, share, ex.Message );
136 public static TreeNode IndexFolder( string directoryName )
138 FileInfo dirinfo = null;
139 TreeNode dir = null;
143 dirinfo = new FileInfo( directoryName );
145 dir = new TreeNode
147 Name = Path.GetFileName( directoryName ),
148 CreationTime = dirinfo.CreationTime,
149 AccessTime = dirinfo.LastAccessTime,
150 ModificationTime = dirinfo.LastWriteTime
153 List<TreeNode> listing = new List<TreeNode>();
157 string[] subdirs = Directory.GetDirectories( directoryName );
158 string[] subfiles = Directory.GetFiles( directoryName );
160 if ( subdirs.Length == 0 && subfiles.Length == 0 )
162 return null;
165 dir.Children
168 from directory in subdirs
169 let child = IndexFolder( directory )
170 where child != null && child.Name != ".svn"
171 select child
172 ).Union(
173 from fileName in subfiles
174 let info = new FileInfo( fileName )
175 select
176 new TreeNode
178 Name = info.Name,
179 Size = info.Length,
180 CreationTime = info.CreationTime,
181 AccessTime = info.LastAccessTime,
182 ModificationTime = info.LastWriteTime
185 ).ToList();
187 catch ( UnauthorizedAccessException ex )
189 Console.Error.WriteLine( "Access denied to {0}", directoryName );
191 catch ( IOException ex )
193 Console.Error.WriteLine( "Cannot read {0}: {1}", directoryName, ex.Message );
196 catch ( IOException ex )
198 Console.Error.WriteLine( "Path {0} not found.", directoryName );
201 return dir;