public Task <IOrleansQueryResult <V> > Lookup(K key)
        {
            if (logger.IsVerbose)
            {
                logger.Verbose("Eager index lookup called for key = {0}", key);
            }
            BucketT targetBucket = RuntimeClient.Current.InternalGrainFactory.GetGrain <BucketT>(
                IndexUtils.GetIndexGrainID(typeof(V), _indexName) + "_" + key.GetHashCode()
                );

            return(targetBucket.Lookup(key));
        }
        /// <summary>
        /// This is a helper method for creating an index on a field of an actor.
        /// </summary>
        /// <param name="gf">The current instance of IGrainFactory</param>
        /// <param name="idxType">The type of index to be created</param>
        /// <param name="indexName">The index name to be created</param>
        /// <param name="isUniqueIndex">Determines whether this is a unique index that needs to be created</param>
        /// <param name="isEager">Determines whether updates to this index should be applied eagerly or not</param>
        /// <param name="maxEntriesPerBucket">Determines the maximum number of entries in
        /// each bucket of a distributed index, if this index type is a distributed one.</param>
        /// <param name="indexedProperty">the PropertyInfo object for the indexed field.
        /// This object helps in creating a default instance of IndexUpdateGenerator.</param>
        /// <returns>A triple that consists of:
        /// 1) the index object (that implements IndexInterface
        /// 2) the IndexMetaData object for this index, and
        /// 3) the IndexUpdateGenerator instance for this index.
        /// This triple is untyped, because IndexInterface, IndexMetaData
        /// and IndexUpdateGenerator types are not visible in the core project.</returns>
        internal static Tuple <object, object, object> CreateIndex(this IGrainFactory gf, Type idxType, string indexName, bool isUniqueIndex, bool isEager, int maxEntriesPerBucket, PropertyInfo indexedProperty)
        {
            Type iIndexType = idxType.GetGenericType(typeof(IndexInterface <,>));

            if (iIndexType != null)
            {
                Type[] indexTypeArgs = iIndexType.GetGenericArguments();
                Type   keyType       = indexTypeArgs[0];
                Type   grainType     = indexTypeArgs[1];

                IndexInterface index;
                if (typeof(IGrain).IsAssignableFrom(idxType))
                {
                    index = (IndexInterface)gf.GetGrain(IndexUtils.GetIndexGrainID(grainType, indexName), idxType, idxType);

                    Type idxImplType = TypeUtils.ResolveType(TypeCodeMapper.GetImplementation(idxType).GrainClass);

                    if (idxImplType.IsGenericTypeDefinition)
                    {
                        idxImplType = idxImplType.MakeGenericType(iIndexType.GetGenericArguments());
                    }

                    MethodInfo initPerSilo;
                    if ((initPerSilo = idxImplType.GetMethod("InitPerSilo", BindingFlags.Static | BindingFlags.Public)) != null)
                    {
                        var initPerSiloMethod = (Action <Silo, string, bool>)Delegate.CreateDelegate(
                            typeof(Action <Silo, string, bool>),
                            initPerSilo);
                        initPerSiloMethod(Silo.CurrentSilo, indexName, isUniqueIndex);
                    }
                }
                else if (idxType.IsClass)
                {
                    index = (IndexInterface)Activator.CreateInstance(idxType, indexName, isUniqueIndex);
                }
                else
                {
                    throw new Exception(string.Format("{0} is neither a grain nor a class. Index \"{1}\" cannot be created.", idxType, indexName));
                }

                return(Tuple.Create((object)index, (object)new IndexMetaData(idxType, isUniqueIndex, isEager, maxEntriesPerBucket), (object)CreateIndexUpdateGenFromProperty(indexedProperty)));
            }
            else
            {
                throw new NotSupportedException(string.Format("Adding an index that does not implement IndexInterface<K,V> is not supported yet. Your requested index ({0}) is invalid.", idxType.ToString()));
            }
        }
        public async Task <bool> DirectApplyIndexUpdate(IIndexableGrain g, Immutable <IMemberUpdate> iUpdate, bool isUniqueIndex, IndexMetaData idxMetaData, SiloAddress siloAddress)
        {
            IMemberUpdate      update = iUpdate.Value;
            IndexOperationType opType = update.GetOperationType();

            if (opType == IndexOperationType.Update)
            {
                int     befImgHash   = update.GetBeforeImage().GetHashCode();
                int     aftImgHash   = update.GetAfterImage().GetHashCode();
                BucketT befImgBucket = InsideRuntimeClient.Current.InternalGrainFactory.GetGrain <BucketT>(
                    IndexUtils.GetIndexGrainID(typeof(V), _indexName) + "_" + befImgHash
                    );
                if (befImgHash == aftImgHash)
                {
                    return(await befImgBucket.DirectApplyIndexUpdate(g, iUpdate, isUniqueIndex, idxMetaData));
                }
                else
                {
                    BucketT aftImgBucket = InsideRuntimeClient.Current.InternalGrainFactory.GetGrain <BucketT>(
                        IndexUtils.GetIndexGrainID(typeof(V), _indexName) + "_" + befImgHash
                        );
                    var    befTask = befImgBucket.DirectApplyIndexUpdate(g, new MemberUpdateOverridenOperation(iUpdate.Value, IndexOperationType.Delete).AsImmutable <IMemberUpdate>(), isUniqueIndex, idxMetaData);
                    var    aftTask = aftImgBucket.DirectApplyIndexUpdate(g, new MemberUpdateOverridenOperation(iUpdate.Value, IndexOperationType.Insert).AsImmutable <IMemberUpdate>(), isUniqueIndex, idxMetaData);
                    bool[] results = await Task.WhenAll(befTask, aftTask);

                    return(results[0] && results[1]);
                }
            }
            else if (opType == IndexOperationType.Insert)
            {
                int     aftImgHash   = update.GetAfterImage().GetHashCode();
                BucketT aftImgBucket = InsideRuntimeClient.Current.InternalGrainFactory.GetGrain <BucketT>(
                    IndexUtils.GetIndexGrainID(typeof(V), _indexName) + "_" + aftImgHash
                    );
                return(await aftImgBucket.DirectApplyIndexUpdate(g, iUpdate, isUniqueIndex, idxMetaData));
            }
            else if (opType == IndexOperationType.Delete)
            {
                int     befImgHash   = update.GetBeforeImage().GetHashCode();
                BucketT befImgBucket = InsideRuntimeClient.Current.InternalGrainFactory.GetGrain <BucketT>(
                    IndexUtils.GetIndexGrainID(typeof(V), _indexName) + "_" + befImgHash
                    );
                return(await befImgBucket.DirectApplyIndexUpdate(g, iUpdate, isUniqueIndex, idxMetaData));
            }
            return(true);
        }
 private static GrainId GetGrainID(string indexName)
 {
     return(GrainId.GetSystemTargetGrainId(Constants.HASH_INDEX_PARTITIONED_PER_SILO_BUCKET_SYSTEM_TARGET_TYPE_CODE,
                                           IndexUtils.GetIndexGrainID(typeof(V), indexName)));
 }
Beispiel #5
0
 private static GrainId GetAHashIndexPartitionedPerSiloGrainID(string indexName, Type iGrainType)
 {
     return(GrainId.GetSystemTargetGrainId(Constants.HASH_INDEX_PARTITIONED_PER_SILO_BUCKET_SYSTEM_TARGET_TYPE_CODE,
                                           IndexUtils.GetIndexGrainID(iGrainType, indexName)));
 }
        public override async Task ObserveResults(IAsyncBatchObserver <TIGrain> observer)
        {
            IndexInterface         index        = GetGrainFactory().GetIndex(_indexName, typeof(TIGrain));
            IAsyncStream <TIGrain> resultStream = GetStreamProvider().GetStream <TIGrain>(Guid.NewGuid(), IndexUtils.GetIndexGrainID(typeof(TIGrain), _indexName));

            IOrleansQueryResultStream <TIGrain> result = new OrleansQueryResultStream <TIGrain>(resultStream);

            //the observer is attached to the query result
            await result.SubscribeAsync(observer);

            //the actual lookup for the query result to be streamed to the observer
            await index.Lookup(result.Cast <IIndexableGrain>(), _param);
        }
        public async Task <bool> DirectApplyIndexUpdateBatch(Immutable <IDictionary <IIndexableGrain, IList <IMemberUpdate> > > iUpdates, bool isUnique, IndexMetaData idxMetaData, SiloAddress siloAddress = null)
        {
            if (logger.IsVerbose)
            {
                logger.Verbose("Started calling DirectApplyIndexUpdateBatch with the following parameters: isUnique = {0}, siloAddress = {1}, iUpdates = {2}", isUnique, siloAddress, MemberUpdate.UpdatesToString(iUpdates.Value));
            }

            IDictionary <IIndexableGrain, IList <IMemberUpdate> > updates = iUpdates.Value;
            IDictionary <int, IDictionary <IIndexableGrain, IList <IMemberUpdate> > > bucketUpdates = new Dictionary <int, IDictionary <IIndexableGrain, IList <IMemberUpdate> > >();

            foreach (var kv in updates)
            {
                IIndexableGrain       g        = kv.Key;
                IList <IMemberUpdate> gUpdates = kv.Value;
                foreach (IMemberUpdate update in gUpdates)
                {
                    IndexOperationType opType = update.GetOperationType();
                    if (opType == IndexOperationType.Update)
                    {
                        int befImgHash = update.GetBeforeImage().GetHashCode();
                        int aftImgHash = update.GetAfterImage().GetHashCode();

                        if (befImgHash == aftImgHash)
                        {
                            AddUpdateToBucket(bucketUpdates, g, befImgHash, update);
                        }
                        else
                        {
                            AddUpdateToBucket(bucketUpdates, g, befImgHash, new MemberUpdateOverridenOperation(update, IndexOperationType.Delete));
                            AddUpdateToBucket(bucketUpdates, g, aftImgHash, new MemberUpdateOverridenOperation(update, IndexOperationType.Insert));
                        }
                    }
                    else if (opType == IndexOperationType.Insert)
                    {
                        int aftImgHash = update.GetAfterImage().GetHashCode();
                        AddUpdateToBucket(bucketUpdates, g, aftImgHash, update);
                    }
                    else if (opType == IndexOperationType.Delete)
                    {
                        int befImgHash = update.GetBeforeImage().GetHashCode();
                        AddUpdateToBucket(bucketUpdates, g, befImgHash, update);
                    }
                }
            }

            List <Task> updateTasks = new List <Task>();
            int         i           = 0;

            foreach (var kv in bucketUpdates)
            {
                BucketT bucket = InsideRuntimeClient.Current.InternalGrainFactory.GetGrain <BucketT>(
                    IndexUtils.GetIndexGrainID(typeof(V), _indexName) + "_" + kv.Key
                    );
                updateTasks.Add(bucket.DirectApplyIndexUpdateBatch(kv.Value.AsImmutable(), isUnique, idxMetaData, siloAddress));
                ++i;
            }
            await Task.WhenAll(updateTasks);

            if (logger.IsVerbose)
            {
                logger.Verbose("Finished calling DirectApplyIndexUpdateBatch with the following parameters: isUnique = {0}, siloAddress = {1}, iUpdates = {2}", isUnique, siloAddress, MemberUpdate.UpdatesToString(iUpdates.Value));
            }

            return(true);
        }