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))); }
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); }