コード例 #1
0
        private static Item GetCurrentItem(JsonOperationContext ctx, TableValueReader reader)
        {
            int size;

            return(new Item
            {
                Data = new BlittableJsonReaderObject(reader.Read(2, out size), size, ctx),
                Key = Encoding.UTF8.GetString(reader.Read(1, out size), size),
                Etag = Bits.SwapBytes(*(long *)reader.Read(3, out size))
            });
        }
コード例 #2
0
        public long ReadLastEtag(TransactionOperationContext ctx)
        {
            var table = ctx.Transaction.InnerTransaction.OpenTable(_itemsSchema, "Items");
            var itemsFromBackwards = table.SeekBackwardFrom(_itemsSchema.FixedSizeIndexes[EtagIndexName], long.MaxValue);
            var reader             = itemsFromBackwards.FirstOrDefault();

            if (reader == null)
            {
                return(0);
            }

            int size;

            return(Bits.SwapBytes(*(long *)reader.Read(3, out size)));
        }
コード例 #3
0
        public unsafe int GetHashCode(StringSegment str)
        {
            if (_buffer == null || _buffer.Length < str.Length)
            {
                _buffer = new char[Bits.NextPowerOf2(str.Length)];
            }

            for (int i = 0; i < str.Length; i++)
            {
                _buffer[i] = char.ToUpperInvariant(str.String[str.Start + i]);
            }

            fixed(char *p = _buffer)
            {
                return((int)Hashing.XXHash32.CalculateInline((byte *)p, str.Length * sizeof(char)));
            }
        }
コード例 #4
0
        public Tuple <BlittableJsonReaderObject, long> ReadWithEtag(TransactionOperationContext ctx, string id)
        {
            var items = ctx.Transaction.InnerTransaction.OpenTable(_itemsSchema, "Items");

            TableValueReader reader;
            Slice            key;

            using (Slice.From(ctx.Allocator, id.ToLowerInvariant(), out key))
            {
                reader = items.ReadByKey(key);
            }
            if (reader == null)
            {
                return(null);
            }
            int size;
            var ptr = reader.Read(2, out size);

            return(Tuple.Create(new BlittableJsonReaderObject(ptr, size, ctx), Bits.SwapBytes(*(long *)reader.Read(3, out size))));
        }
コード例 #5
0
        public unsafe int GetHashCode(StringSegment str)
        {
            if (_buffer == null || _buffer.Length < str.Length)
            {
                _buffer = new char[Bits.NextPowerOf2(str.Length)];
            }

            for (int i = 0; i < str.Length; i++)
            {
                _buffer[i] = char.ToUpperInvariant(str.Buffer[str.Offset + i]);
            }

            fixed(char *p = _buffer)
            {
                //PERF: JIT will remove the corresponding line based on the target architecture using dead code removal.
                if (IntPtr.Size == 4)
                {
                    return((int)Hashing.XXHash32.CalculateInline((byte *)p, str.Length * sizeof(char)));
                }
                return((int)Hashing.XXHash64.CalculateInline((byte *)p, (ulong)str.Length * sizeof(char)));
            }
        }
コード例 #6
0
        public long Write(TransactionOperationContext ctx, string id, BlittableJsonReaderObject doc, long?expectedEtag = null)
        {
            TrackChangeAfterTransactionCommit(ctx, "Write", id);
            var newEtag = _lastEtag + 1;

            Slice idAsSlice;
            Slice loweredId;

            using (Slice.From(ctx.Allocator, id, out idAsSlice))
                using (Slice.From(ctx.Allocator, id.ToLowerInvariant(), out loweredId))
                {
                    var newEtagBigEndian = Bits.SwapBytes(newEtag);
                    var itemTable        = ctx.Transaction.InnerTransaction.OpenTable(_itemsSchema, "Items");

                    var oldValue = itemTable.ReadByKey(loweredId);
                    if (oldValue == null)
                    {
                        if (expectedEtag != null && expectedEtag != 0)
                        {
                            throw new ConcurrencyException(
                                      $"Server store item {id} does not exists, but Write was called with etag {expectedEtag}. Optimistic concurrency violation, transaction will be aborted.")
                                  {
                                      ExpectedETag = (long)expectedEtag
                                  };
                        }

                        itemTable.Insert(new TableValueBuilder
                        {
                            loweredId,
                            idAsSlice,
                            { doc.BasePointer, doc.Size },
                            {&newEtagBigEndian, sizeof(long) }
                        });
                    }
                    else
                    {
                        int size;
                        var test    = GetCurrentItem(ctx, oldValue);
                        var oldEtag = Bits.SwapBytes(*(long *)oldValue.Read(3, out size));
                        if (expectedEtag != null && oldEtag != expectedEtag)
                        {
                            throw new ConcurrencyException(
                                      $"Server store item {id} has etag {oldEtag}, but Write was called with etag {expectedEtag}. Optimistic concurrency violation, transaction will be aborted.")
                                  {
                                      ActualETag   = oldEtag,
                                      ExpectedETag = (long)expectedEtag
                                  }
                        }
                        ;

                        itemTable.Update(oldValue.Id, new TableValueBuilder
                        {
                            loweredId,
                            idAsSlice,
                            { doc.BasePointer, doc.Size },
                            {&newEtagBigEndian, sizeof(long) }
                        });
                    }
                }
            _lastEtag++;
            return(newEtag);
        }
コード例 #7
0
        public void Initialize()
        {
            _shutdownNotification = new CancellationTokenSource();

            AbstractLowMemoryNotification.Initialize(ServerShutdown, Configuration);

            if (_logger.IsInfoEnabled)
            {
                _logger.Info("Starting to open server store for " + (Configuration.Core.RunInMemory ? "<memory>" : Configuration.Core.DataDirectory));
            }

            var options = Configuration.Core.RunInMemory
                ? StorageEnvironmentOptions.CreateMemoryOnly(Configuration.Core.DataDirectory)
                : StorageEnvironmentOptions.ForPath(System.IO.Path.Combine(Configuration.Core.DataDirectory, "System"));

            options.SchemaVersion = 2;

            try
            {
                StorageEnvironment.MaxConcurrentFlushes = Configuration.Storage.MaxConcurrentFlushes;
                _env = new StorageEnvironment(options);
                using (var tx = _env.WriteTransaction())
                {
                    tx.DeleteTree("items");// note the different casing, we remove the old items tree
                    _itemsSchema.Create(tx, "Items", 16);
                    tx.Commit();
                }

                using (var tx = _env.ReadTransaction())
                {
                    var table = tx.OpenTable(_itemsSchema, "Items");
                    var itemsFromBackwards = table.SeekBackwardFrom(_itemsSchema.FixedSizeIndexes[EtagIndexName], long.MaxValue);
                    var reader             = itemsFromBackwards.FirstOrDefault();
                    if (reader == null)
                    {
                        _lastEtag = 0;
                    }
                    else
                    {
                        int size;
                        _lastEtag = Bits.SwapBytes(*(long *)reader.Read(3, out size));
                    }
                }
            }
            catch (Exception e)
            {
                if (_logger.IsOperationsEnabled)
                {
                    _logger.Operations(
                        "Could not open server store for " + (Configuration.Core.RunInMemory ? "<memory>" : Configuration.Core.DataDirectory), e);
                }
                options.Dispose();
                throw;
            }

            ContextPool = new TransactionContextPool(_env);
            _timer      = new Timer(IdleOperations, null, _frequencyToCheckForIdleDatabases, TimeSpan.FromDays(7));
            Alerts.Initialize(_env, ContextPool);
            DatabaseInfoCache.Initialize(_env, ContextPool);
            LicenseStorage.Initialize(_env, ContextPool);
        }