예제 #1
0
        public void TryCopy(IEnumerable <KeyValuePair <string, string> > keyCopies, DateTimeOffset expiry, out HashSet <string> fromKeysWhichDidNotExist,
                            out HashSet <string> toKeysWhichAlreadyExisted, AvailabilityLevel requiredAvailabilityLevel = AvailabilityLevel.SavedToDisk)
        {
            var(notExists1, existed1) = _lmdb.WriteAsync(txn =>
            {
                var notExists = new List <string>();
                var existed   = new List <string>();

                foreach (var fromTo in keyCopies)
                {
                    var from = new TableKey(fromTo.Key);
                    var to   = new TableKey(fromTo.Value);

                    var val = txn.TryGet(_kvTable, from);
                    if (!val.HasValue)
                    {
                        notExists.Add(fromTo.Key);
                    }
                    else if (txn.ContainsKey(_kvTable, to))
                    {
                        existed.Add(fromTo.Value);
                    }
                    else
                    {
                        txn.Add(_kvTable, to, val.Value);
                    }
                }

                return(notExists, existed);
            }, false).Result;

            fromKeysWhichDidNotExist  = new HashSet <string>(notExists1);
            toKeysWhichAlreadyExisted = new HashSet <string>(existed1);
        }
예제 #2
0
        public void TryCopy(IEnumerable <KeyValuePair <string, string> > keyCopies, DateTimeOffset expiry, out HashSet <string> fromKeysWhichDidNotExist,
                            out HashSet <string> toKeysWhichAlreadyExisted, AvailabilityLevel requiredAvailabilityLevel = AvailabilityLevel.SavedToDisk)
        {
            var keysCopied = keyCopies.ToArray();

            var request = new CopyRequest {
                CorrelationId = _correlationId
            };

            request.Entries.AddRange(keysCopied.Select(kv => new CopyRequest.Types.CopyRequestEntry {
                Expiry = expiry.ToTimestamp()
            }));
            var copyResponse = Task.Run(async() => await _lightClient.CopyAsync(request)).GetAwaiter().GetResult();

            var ret = copyResponse.Results.
                      Select((r, i) => (r, i)).
                      Aggregate((new List <string>(), new List <string>()), (acc, res) =>
            {
                switch (res.Item1)
                {
                case CopyResponse.Types.CopyResult.Success:
                    break;

                case CopyResponse.Types.CopyResult.FromKeyNotFound:
                    acc.Item1.Add(keysCopied[res.Item2].Key);
                    break;

                case CopyResponse.Types.CopyResult.ToKeyExists:
                    acc.Item2.Add(keysCopied[res.Item2].Value);
                    break;

                case CopyResponse.Types.CopyResult.Failure:         // TODO: What to do in a case of failures?
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }

                return(acc);
            });

            fromKeysWhichDidNotExist  = ret.Item1.ToHashSet();
            toKeysWhichAlreadyExisted = ret.Item2.ToHashSet();
        }
예제 #3
0
        private HashSet <string> TryAdd(IEnumerable <string> keys, Action <string, Stream> streamWriter, bool allowOverride,
                                        DateTimeOffset expiry, AvailabilityLevel requiredAvailabilityLevel)
        {
            // TODO: Add reactions to other AvailabilityLevels
            // TODO: Deal with expiration
            var batch = keys.Select(k => (k, new MemoryStream())).ToArray();

            foreach (var ks in batch)
            {
                streamWriter(ks.Item1, ks.Item2);
                ks.Item2.Position = 0;
            }

            var preparedBatch = batch.Select(ks => (new TableKey(ks.Item1), new TableValue(ks.Item2))).ToArray();

            var ret = _lmdb.WriteAsync(txn => allowOverride ? txn.AddOrUpdateBatch(_kvTable, preparedBatch) : txn.AddBatch(_kvTable, preparedBatch), false).Result;

            return(new HashSet <string>(ret.Where(kb => kb.Item2).Select(kb => kb.Item1.ToString()))); // TODO: Reconfirm if successful or failed keys should be returned
        }
예제 #4
0
        private IEnumerable <string> TryAdd(IEnumerable <string> keys, Action <string, Stream> streamWriter, bool allowOverride,
                                            DateTimeOffset expiry, AvailabilityLevel requiredAvailabilityLevel)
        {
            // TODO: Add reactions to other AvailabilityLevels

            var preparedBatch = new List <AddRequestEntry>();

            foreach (var key in keys)
            {
                using (var valueStream = new MemoryStream())
                    using (var compressedStream = new LightWriteStream(ValueCompressor.Compress(_clientConfig.Compression, valueStream)))
                    {
                        streamWriter(key, compressedStream);
                        compressedStream.Flush();
                        valueStream.Position = 0;
                        var value = valueStream.ToByteArray();

                        var entry = new AddRequestEntry
                        {
                            Key           = key,
                            Expiry        = expiry.ToTimestamp(),
                            ValueMetadata = new ValueMetadata
                            {
                                Compression    = _clientConfig.Compression,
                                HashedWith     = _clientConfig.HashedWith,
                                Hash           = ByteString.CopyFrom(_valueHasher.ComputeHash(_clientConfig.HashedWith, value)),
                                SizeFull       = (uint)compressedStream.Position,
                                SizeCompressed = (uint)value.Length
                            },
                            Value = ByteString.CopyFrom(value)
                        };

                        preparedBatch.Add(entry);
                    }
            }

            var addResponse = Task.Run(async() =>
            {
                if (_clientConfig.UseStreaming)
                {
                    return(await AddStreaming(preparedBatch, allowOverride));
                }

                var request = new AddRequest
                {
                    Header = new Header
                    {
                        OverrideExisting = allowOverride,
                        CorrelationId    = _correlationId,
                        ChunksCount      = (uint)preparedBatch.Count
                    }
                };
                request.Entries.Add(preparedBatch);
                return(await _lightClient.AddAsync(request));
            }).GetAwaiter().GetResult();

            return(addResponse.Results.
                   Select((r, i) => (r, i)).
                   Where(res => res.Item1 == AddResponse.Types.AddResult.KeyAdded).
                   Select(res => preparedBatch[res.Item2].Key).ToHashSet()); // TODO: Reconfirm if successful or failed keys should be returned
        }
예제 #5
0
 public HashSet <string> TryAddOrUpdate(IEnumerable <string> keys, Action <string, Stream> streamWriter, DateTimeOffset expiry,
                                        AvailabilityLevel requiredAvailabilityLevel = AvailabilityLevel.SavedToDisk) => TryAdd(keys, streamWriter, true, expiry, requiredAvailabilityLevel).ToHashSet();
예제 #6
0
 public void TryCopy(IEnumerable <KeyValuePair <string, string> > keyCopies, DateTimeOffset expiry, out HashSet <string> fromKeysWhichDidNotExist, out HashSet <string> toKeysWhichAlreadyExisted, AvailabilityLevel requiredAvailabilityLevel = AvailabilityLevel.SavedToDisk) =>
 _client.TryCopy(keyCopies, expiry, out fromKeysWhichDidNotExist, out toKeysWhichAlreadyExisted, requiredAvailabilityLevel);
예제 #7
0
 public HashSet <string> TryAdd(IEnumerable <string> keys, Action <string, Stream> streamWriter, DateTimeOffset expiry, AvailabilityLevel requiredAvailabilityLevel = AvailabilityLevel.SavedToDisk) =>
 _client.TryAdd(keys, streamWriter, expiry, requiredAvailabilityLevel);
예제 #8
0
 public Template()
 {
     Frames       = new List <TemplateFrame>();
     Availability = AvailabilityLevel.Series;
 }