Exemplo n.º 1
0
        public long?GetCounterValue(DocumentsOperationContext context, string docId, string counterName)
        {
            var table = new Table(CountersSchema, context.Transaction.InnerTransaction);

            using (GetCounterPartialKey(context, docId, counterName, out var key))
            {
                long?value = null;
                foreach (var result in table.SeekByPrimaryKeyPrefix(key, Slices.Empty, 0))
                {
                    value = value ?? 0;
                    var pCounterDbValue = result.Value.Reader.Read((int)CountersTable.Value, out var size);
                    Debug.Assert(size == sizeof(long));
                    try
                    {
                        value = checked (value + *(long *)pCounterDbValue);
                    }
                    catch (OverflowException e)
                    {
                        CounterOverflowException.ThrowFor(docId, counterName, e);
                    }
                }

                return(value);
            }
        }
Exemplo n.º 2
0
        private static void GetCounterValue(DocumentsOperationContext context, DocumentDatabase database, string docId,
                                            string counterName, bool addFullValues, CountersDetail result)
        {
            var  fullValues = addFullValues ? new Dictionary <string, long>() : null;
            long?value      = null;

            foreach (var(cv, val) in database.DocumentsStorage.CountersStorage.GetCounterValues(context,
                                                                                                docId, counterName))
            {
                value = value ?? 0;
                try
                {
                    value = checked (value + val);
                }
                catch (OverflowException e)
                {
                    CounterOverflowException.ThrowFor(docId, counterName, e);
                }

                if (addFullValues)
                {
                    fullValues[cv] = val;
                }
            }

            if (value == null)
            {
                return;
            }

            if (result.Counters == null)
            {
                result.Counters = new List <CounterDetail>();
            }

            result.Counters.Add(new CounterDetail
            {
                DocumentId    = docId,
                CounterName   = counterName,
                TotalValue    = value.Value,
                CounterValues = fullValues
            });
        }
Exemplo n.º 3
0
        public string IncrementCounter(DocumentsOperationContext context, string documentId, string collection, string name, long delta, out bool exists)
        {
            if (context.Transaction == null)
            {
                DocumentPutAction.ThrowRequiresTransaction();
                Debug.Assert(false);// never hit
            }

            var collectionName = _documentsStorage.ExtractCollectionName(context, collection);
            var table          = GetCountersTable(context.Transaction.InnerTransaction, collectionName);

            using (GetCounterKey(context, documentId, name, context.Environment.Base64Id, out var counterKey))
            {
                var value = delta;
                exists = table.ReadByKey(counterKey, out var existing);
                if (exists)
                {
                    var prev = *(long *)existing.Read((int)CountersTable.Value, out var size);
                    Debug.Assert(size == sizeof(long));
                    try
                    {
                        value = checked (prev + delta); //inc
                    }
                    catch (OverflowException e)
                    {
                        CounterOverflowException.ThrowFor(documentId, name, prev, delta, e);
                    }
                }

                RemoveTombstoneIfExists(context, documentId, name);

                var etag   = _documentsStorage.GenerateNextEtag();
                var result = ChangeVectorUtils.TryUpdateChangeVector(_documentDatabase.ServerStore.NodeTag, _documentsStorage.Environment.Base64Id, etag, string.Empty);

                using (Slice.From(context.Allocator, result.ChangeVector, out var cv))
                    using (DocumentIdWorker.GetStringPreserveCase(context, name, out Slice nameSlice))
                        using (DocumentIdWorker.GetStringPreserveCase(context, collectionName.Name, out Slice collectionSlice))
                            using (table.Allocate(out TableValueBuilder tvb))
                            {
                                tvb.Add(counterKey);
                                tvb.Add(nameSlice);
                                tvb.Add(Bits.SwapBytes(etag));
                                tvb.Add(value);
                                tvb.Add(cv);
                                tvb.Add(collectionSlice);
                                tvb.Add(context.TransactionMarkerOffset);

                                table.Set(tvb);
                            }

                UpdateMetrics(counterKey, name, result.ChangeVector, collection);

                context.Transaction.AddAfterCommitNotification(new CounterChange
                {
                    ChangeVector = result.ChangeVector,
                    DocumentId   = documentId,
                    Name         = name,
                    Type         = exists ? CounterChangeTypes.Increment : CounterChangeTypes.Put,
                    Value        = value
                });

                return(result.ChangeVector);
            }
        }