Пример #1
0
        /// <summary>
        /// Crop a store, generating a new store.
        /// </summary>
        /// <param name="store">Store name.</param>
        /// <param name="path">Store path.</param>
        /// <param name="output">Output store name.</param>
        /// <param name="outputPath">Output store path.</param>
        /// <param name="start">Start time relative to beginning.</param>
        /// <param name="length">Length relative to start.</param>
        /// <returns>Success flag.</returns>
        internal static int CropStore(string store, string path, string output, string outputPath, string start, string length)
        {
            Console.WriteLine($"Cropping store (store={store}, path={path}, output={output}, outputpath={outputPath}, start={start}, length={length})");

            var startTime = TimeSpan.Zero; // start at beginning if unspecified

            if (!string.IsNullOrWhiteSpace(start) && !TimeSpan.TryParse(start, CultureInfo.InvariantCulture, out startTime))
            {
                throw new Exception($"Could not parse start time '{start}' (see https://docs.microsoft.com/en-us/dotnet/api/system.timespan.parse for valid format).");
            }

            var lengthRelativeInterval = RelativeTimeInterval.LeftBounded(TimeSpan.Zero); // continue to end if unspecified

            if (!string.IsNullOrWhiteSpace(length))
            {
                if (TimeSpan.TryParse(length, CultureInfo.InvariantCulture, out var lengthTimeSpan))
                {
                    lengthRelativeInterval = RelativeTimeInterval.Future(lengthTimeSpan);
                }
                else
                {
                    throw new Exception($"Could not parse length '{length}' (see https://docs.microsoft.com/en-us/dotnet/api/system.timespan.parse for valid format).");
                }
            }

            if (PsiStore.Exists(output, outputPath) && !ConfirmStoreOverwrite(output))
            {
                return(-1);
            }

            PsiStore.Crop((store, path), (output, outputPath), startTime, lengthRelativeInterval, false, new Progress <double>(p => Console.WriteLine($"Progress: {p * 100.0:F2}%")), Console.WriteLine);
            return(0);
        }
Пример #2
0
        public async Task SessionCreateDerivedPartitionCancellation()
        {
            var dataset = new Dataset();
            var session = dataset.CreateSession();

            // generate a test store
            var originalStoreName = "OriginalStore";

            GenerateTestStore(originalStoreName, StorePath);

            // add a partition
            var partition0 = session.AddPsiStorePartition(originalStoreName, StorePath, "Partition_0");

            Assert.AreEqual(1, session.Partitions.Count);
            Assert.AreEqual("Partition_0", session.Partitions[0].Name);

            int multiplier = 7;

            try
            {
                // create a cancellation token source that will automatically request cancellation after 500 ms
                var cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(500));

                // create a derived partition which contains the values from the original stream multiplied by a multiplier
                await session.CreateDerivedPsiPartitionAsync(
                    (pipeline, importer, exporter, parameter) =>
                {
                    var inputStream   = importer.OpenStream <int>("Root");
                    var derivedStream = inputStream.Sample(TimeSpan.FromMinutes(1), RelativeTimeInterval.Infinite).Select(x => x *parameter).Write("DerivedStream", exporter);

                    // add a dummy source and propose a long time interval so that the operation will block (and eventually be canceled)
                    var generator          = Generators.Repeat(pipeline, 0, int.MaxValue, TimeSpan.FromMilliseconds(1000));
                    var replayTimeInterval = TimeInterval.LeftBounded(importer.MessageOriginatingTimeInterval.Left);
                    pipeline.ProposeReplayTime(replayTimeInterval);
                },
                    multiplier,
                    "Partition_1",
                    false,
                    "DerivedStore",
                    StorePath,
                    null,
                    null,
                    cts.Token);
            }
            catch (OperationCanceledException)
            {
                // should NOT have created a new partition (but original partition should be intact)
                Assert.AreEqual(1, session.Partitions.Count);
                Assert.IsTrue(PsiStore.Exists("OriginalStore", StorePath));
                Assert.IsFalse(PsiStore.Exists("DerivedStore", StorePath));

                // verify original partition metadata
                var originalPartition = session.Partitions[0] as Partition <PsiStoreStreamReader>;
                Assert.AreEqual("Partition_0", originalPartition.Name);
                Assert.AreEqual("OriginalStore", originalPartition.StoreName);
                Assert.AreEqual($"{StorePath}{Path.DirectorySeparatorChar}OriginalStore.0000", originalPartition.StorePath);

                throw;
            }
        }
Пример #3
0
        /// <summary>
        /// Concatenate a set of stores, generating a new store.
        /// </summary>
        /// <param name="stores">Store names (semicolon separated).</param>
        /// <param name="path">Store path.</param>
        /// <param name="output">Output store name.</param>
        /// <param name="outputPath">Output store path.</param>
        /// <returns>Success flag.</returns>
        internal static int ConcatenateStores(string stores, string path, string output, string outputPath)
        {
            Console.WriteLine($"Concatenating stores (stores={stores}, path={path}, output={output}, outputpath={outputPath})");

            if (PsiStore.Exists(output, outputPath) && !ConfirmStoreOverwrite(output))
            {
                return(-1);
            }

            PsiStore.Concatenate(stores.Split(';').Select(s => (s, path)), (output, outputPath), false, new Progress <double>(p => Console.WriteLine($"Progress: {p * 100.0:F2}%")), Console.WriteLine);
            return(0);
        }
Пример #4
0
        public async Task SessionCreateDerivedPartition()
        {
            var dataset = new Dataset();
            var session = dataset.CreateSession();

            // generate a test store
            var originalStoreName = "OriginalStore";

            GenerateTestStore(originalStoreName, StorePath);

            // add a partition
            var partition0 = session.AddPsiStorePartition(originalStoreName, StorePath, "Partition_0");

            Assert.AreEqual(1, session.Partitions.Count);
            Assert.AreEqual("Partition_0", session.Partitions[0].Name);

            int multiplier = 7;

            // create a derived partition which contains the values from the original stream multiplied by a multiplier
            await session.CreateDerivedPsiPartitionAsync(
                (pipeline, importer, exporter, parameter) =>
            {
                var inputStream   = importer.OpenStream <int>("Root");
                var derivedStream = inputStream.Select(x => x *parameter).Write("DerivedStream", exporter);
            },
                multiplier,
                "Partition_1",
                false,
                "DerivedStore",
                StorePath);

            // should have created a new store partition
            Assert.AreEqual(2, session.Partitions.Count);
            Assert.IsTrue(PsiStore.Exists("OriginalStore", StorePath));
            Assert.IsTrue(PsiStore.Exists("DerivedStore", StorePath));

            // verify partition metadata
            var originalPartition = session.Partitions[0] as Partition <PsiStoreStreamReader>;

            Assert.AreEqual("Partition_0", originalPartition.Name);
            Assert.AreEqual("OriginalStore", originalPartition.StoreName);
            Assert.AreEqual($"{StorePath}{Path.DirectorySeparatorChar}OriginalStore.0000", originalPartition.StorePath);

            var derivedPartition = session.Partitions[1] as Partition <PsiStoreStreamReader>;

            Assert.AreEqual("Partition_1", derivedPartition.Name);
            Assert.AreEqual("DerivedStore", derivedPartition.StoreName);
            Assert.AreEqual(StorePath, derivedPartition.StorePath);

            // collections to capture stream values
            var originalValues = new List <int>();
            var originalTimes  = new List <DateTime>();
            var derivedValues  = new List <int>();
            var derivedTimes   = new List <DateTime>();

            // read stream values from the partitions
            using (var pipeline = Pipeline.Create())
            {
                var originalPartitionImporter = PsiStore.Open(pipeline, originalPartition.StoreName, originalPartition.StorePath);
                originalPartitionImporter.OpenStream <int>("Root").Do(
                    (i, e) =>
                {
                    originalValues.Add(i);
                    originalTimes.Add(e.OriginatingTime);
                });

                var derivedPartitionImporter = PsiStore.Open(pipeline, derivedPartition.StoreName, derivedPartition.StorePath);
                derivedPartitionImporter.OpenStream <int>("DerivedStream").Do(
                    (i, e) =>
                {
                    derivedValues.Add(i);
                    derivedTimes.Add(e.OriginatingTime);
                });

                pipeline.Run();
            }

            // verify that we read the data
            Assert.AreEqual(10, originalValues.Count);
            Assert.AreEqual(10, originalTimes.Count);
            Assert.AreEqual(10, derivedValues.Count);
            Assert.AreEqual(10, derivedTimes.Count);

            // verify values from both streams are what we expect
            CollectionAssert.AreEqual(originalValues.Select(x => x * multiplier).ToList(), derivedValues);
            CollectionAssert.AreEqual(originalTimes, derivedTimes);
        }