using HEAL.Attic; using HeuristicLab.Common; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; using System.Text; using System.Threading.Tasks; namespace HeuristicLab.Algorithms.OESRALPS.DriftDetection { [StorableType("714CE0E4-188F-44A1-A2D0-92F4D82D2C04")] public class BucketContainer { [Storable] private Bucket[] buckets; [Storable] internal BucketContainer Prev { get; set; } [Storable] internal BucketContainer Next { get; set; } [Storable] public int MaxBuckets { get; } [Storable] public int FirstBucket { get; set; } [Storable] public int NumElementsPerBucket { get; set; } [Storable] public int NumBuckets { get; set; } public BucketContainer () { } public BucketContainer(BucketContainer prev, BucketContainer next, int maxBuckets, int elementsPerBucket) { Prev = prev; Next = next; MaxBuckets = maxBuckets; NumElementsPerBucket = elementsPerBucket; buckets = new Bucket[maxBuckets]; FirstBucket = 0; NumBuckets = 0; } private BucketContainer(BucketContainer originalContainer) { MaxBuckets = originalContainer.MaxBuckets; Array.Copy(originalContainer.buckets, 0, buckets, 0, originalContainer.buckets.Length); FirstBucket = originalContainer.FirstBucket; NumElementsPerBucket = originalContainer.NumElementsPerBucket; NumBuckets = originalContainer.NumBuckets; } public void AddBucket(Bucket newBucket) { if (newBucket.NumElements != NumElementsPerBucket) throw new Exception("Number of elements should be number of elements per bucket."); buckets[(FirstBucket + NumBuckets) % MaxBuckets] = newBucket; NumBuckets++; } public Bucket[] RemoveBuckets(int num) { Bucket[] resultBuckets = new Bucket[num]; if (FirstBucket <= ((FirstBucket + num) % MaxBuckets)) { Array.Copy(buckets, FirstBucket, resultBuckets, 0, num); } else { Array.Copy(buckets, FirstBucket, resultBuckets, 0, MaxBuckets - FirstBucket); Array.Copy(buckets, 0, resultBuckets, MaxBuckets - FirstBucket, num - MaxBuckets + FirstBucket); } FirstBucket = (FirstBucket + num) % MaxBuckets; NumBuckets -= num; return resultBuckets; } public Bucket GetBucket(int position) { return buckets[(FirstBucket + (NumBuckets - position - 1)) % MaxBuckets]; } public BucketContainer DeepCopy() { if (!typeof(BucketContainer).IsSerializable) { throw new ArgumentException("The type must be serializable.", "source"); } // Don't serialize a null object, simply return the default for that object if (ReferenceEquals(this, null)) { BucketContainer copyThis = new BucketContainer(this); if (Next != null) { BucketContainer nextCopy = Next.DeepCopy(); copyThis.Next = nextCopy; nextCopy.Prev = copyThis; } return copyThis; } IFormatter formatter = new BinaryFormatter(); using (Stream stream = new MemoryStream()) { formatter.Serialize(stream, this); stream.Seek(0, SeekOrigin.Begin); BucketContainer copyThis = (BucketContainer)formatter.Deserialize(stream); if (Next != null) { BucketContainer nextCopy = Next.DeepCopy(); copyThis.Next = nextCopy; nextCopy.Prev = copyThis; } return copyThis; } } } }