Beispiel #1
0
        /// <summary>Remove an entity from the index</summary>
        /// <param name="trans">Transaction to use</param>
        /// <param name="id">Id of the entity that has been deleted</param>
        /// <param name="value">Previous value of the entity in the index</param>
        public async Task <bool> RemoveAsync(IFdbTransaction trans, long id, TValue value)
        {
            if (trans == null)
            {
                throw new ArgumentNullException(nameof(trans));
            }

            var key  = this.Subspace[value];
            var data = await trans.GetAsync(key).ConfigureAwait(false);

            if (data.HasValue)
            {
                var builder = new CompressedBitmapBuilder(MutableSlice.AsUnsafeMutableSlice(data));
                builder.Clear((int)id);                 //BUGBUG: 64 bit id!
                trans.Set(key, builder.ToSlice());
                return(true);
            }
            return(false);
        }
Beispiel #2
0
        /// <summary>Returns a list of ids matching a specific value</summary>
        /// <param name="trans"></param>
        /// <param name="value">Value to lookup</param>
        /// <param name="reverse"></param>
        /// <returns>List of document ids matching this value for this particular index (can be empty if no document matches)</returns>
        public async Task <IEnumerable <long>?> LookupAsync(IFdbReadOnlyTransaction trans, TValue value, bool reverse = false)
        {
            var key  = this.Subspace[value];
            var data = await trans.GetAsync(key).ConfigureAwait(false);

            if (data.IsNull)
            {
                return(null);
            }
            if (data.IsEmpty)
            {
                return(Enumerable.Empty <long>());
            }
            var bitmap = new CompressedBitmap(MutableSlice.AsUnsafeMutableSlice(data));

            if (reverse)
            {
                throw new NotImplementedException();                      //TODO: GetView(reverse:true) !
            }
            return(bitmap.GetView().Select(x => (long)x /*BUGBUG 64 bits*/));
        }
Beispiel #3
0
        /// <summary>Update the indexed values of an entity</summary>
        /// <param name="trans">Transaction to use</param>
        /// <param name="id">Id of the entity that has changed</param>
        /// <param name="newValue">Previous value of this entity in the index</param>
        /// <param name="previousValue">New value of this entity in the index</param>
        /// <returns>True if a change was performed in the index; otherwise false (if <paramref name="previousValue"/> and <paramref name="newValue"/>)</returns>
        /// <remarks>If <paramref name="newValue"/> and <paramref name="previousValue"/> are identical, then nothing will be done. Otherwise, the old index value will be deleted and the new value will be added</remarks>
        public async Task <bool> UpdateAsync(IFdbTransaction trans, long id, TValue newValue, TValue previousValue)
        {
            if (trans == null)
            {
                throw new ArgumentNullException(nameof(trans));
            }

            if (!this.ValueComparer.Equals(newValue, previousValue))
            {
                // remove previous value
                if (this.IndexNullValues || previousValue != null)
                {
                    var key  = this.Subspace[previousValue];
                    var data = await trans.GetAsync(key).ConfigureAwait(false);

                    if (data.HasValue)
                    {
                        var builder = new CompressedBitmapBuilder(MutableSlice.AsUnsafeMutableSlice(data));
                        builder.Clear((int)id);                         //BUGBUG: 64 bit id!
                        trans.Set(key, builder.ToSlice());
                    }
                }

                // add new value
                if (this.IndexNullValues || newValue != null)
                {
                    var key  = this.Subspace[newValue];
                    var data = await trans.GetAsync(key).ConfigureAwait(false);

                    var builder = data.HasValue ? new CompressedBitmapBuilder(MutableSlice.AsUnsafeMutableSlice(data)) : CompressedBitmapBuilder.Empty;
                    builder.Set((int)id);                     //BUGBUG: 64 bit id!
                    trans.Set(key, builder.ToSlice());
                }

                // cannot be both null, so we did at least something)
                return(true);
            }
            return(false);
        }
Beispiel #4
0
        /// <summary>Insert a newly created entity to the index</summary>
        /// <param name="trans">Transaction to use</param>
        /// <param name="id">Id of the new entity (that was never indexed before)</param>
        /// <param name="value">Value of this entity in the index</param>
        /// <returns>True if a value was inserted into the index; or false if <paramref name="value"/> is null and <see cref="IndexNullValues"/> is false, or if this <paramref name="id"/> was already indexed at this <paramref name="value"/>.</returns>
        public async Task <bool> AddAsync(IFdbTransaction trans, long id, TValue value)
        {
            if (trans == null)
            {
                throw new ArgumentNullException(nameof(trans));
            }

            if (this.IndexNullValues || value != null)
            {
                var key  = this.Subspace[value];
                var data = await trans.GetAsync(key).ConfigureAwait(false);

                var builder = data.HasValue ? new CompressedBitmapBuilder(MutableSlice.AsUnsafeMutableSlice(data)) : CompressedBitmapBuilder.Empty;

                //TODO: wasteful to crate a builder to only set on bit ?
                builder.Set((int)id);                 //BUGBUG: id should be 64-bit!

                //TODO: if bit was already set, skip the set ?
                trans.Set(key, builder.ToSlice());
                return(true);
            }
            return(false);
        }