private void WorkerOnDoWork(object sender, DoWorkEventArgs e) { var hashargs = (HashArgs)e.Argument; var lines = File.ReadLines(hashargs.Path).ToArray(); int pageCount; int pageSize; int progress = 0; if (hashargs.Choice == HashArgs.InputChoice.PageCount) { pageCount = hashargs.Input; pageSize = (int)Math.Ceiling((decimal)((float)lines.Length / pageCount)); } else { pageSize = hashargs.Input; pageCount = (int)Math.Ceiling((decimal)((float)lines.Length / pageSize)); } var pageTable = new PageTable <string>(pageCount, pageSize); var hashStorage = new HashStorage <Address>(hashargs.BucketCount, hashargs.BucketSize); for (int i = 0; i < pageTable.Pages.Length; i++) { Pages.Add(new List <PageRepresentation>()); } var pageRepresentations = new List <PageRepresentation>(); var bucketRepresentations = new List <BucketRepresentation>(); for (int i = 0; i < lines.Length; i++) { var p = i * 100 / lines.Length; if (p > progress) { progress = p; _worker.ReportProgress(progress); } var address = pageTable.Insert(lines[i]); var rep = new PageRepresentation { Page = address.Page + 1, Line = address.Line + 1, Index = i, Text = lines[i] }; Pages[address.Page].Add(rep); pageRepresentations.Add(rep); hashStorage.Insert(lines[i], address); } var buckets = hashStorage.Buckets; string buildContent(HashStorage <Address> .Entry[] entries) { var res = "["; for (int i = 0; i < entries.Length; i++) { if (entries[i] != null) { res += $"{entries[i].key}-P{entries[i].value.Page+1}L{entries[i].value.Line+1}"; } if (i != entries.Length - 1) { res += ","; } } return(res + "]"); } for (int i = 0; i < buckets.Length; i++) { int counter = 0; var bucket = buckets[i]; while (bucket != null) { bucketRepresentations.Add(new BucketRepresentation { BucketID = $"{i}-{counter}", Content = buildContent(bucket.Entries), Overflow = bucket.Next != null ? $"{i}-{counter+1}": "" }); bucket = bucket.Next; counter++; } } var collisionPct = (float)hashStorage.collisionCount * 100 / lines.Length; var overflowPct = (float)hashStorage.Buckets.Aggregate(0, (i, b) => { if (b.Next != null) { return(i + 1); } return(i); }) * 100 / hashStorage.Buckets.Length; var usedBuckets = hashStorage.Buckets.Where(b => !b.Empty).ToArray(); var avgAccess = (float)usedBuckets .Sum(b => b.Count()) / usedBuckets.Count(); e.Result = new HashResult { PageRepresentations = pageRepresentations, BucketRepresentations = bucketRepresentations, Storage = hashStorage, PageTable = pageTable, collisionsPct = collisionPct, overflowPct = overflowPct, avgAccess = avgAccess }; }