async Task <List <string> > PrepareTopicHashSubscriptions(TopicHashSelector selector) { Dictionary <string, List <string> > topicsByPublisher; Dictionary <string, List <string> > singleWildcardTopicsByPublisher; Dictionary <string, List <string> > multiWildcardTopicsByPublisher; const int NumPublishers = 1; const int NumTopicsPerPublisher = 10000; TopicGenerator.Generate(NumPublishers, NumTopicsPerPublisher, out topicsByPublisher, out singleWildcardTopicsByPublisher, out multiWildcardTopicsByPublisher); var topics = topicsByPublisher.FirstOrDefault().Value; var singleWildcardTopics = singleWildcardTopicsByPublisher.FirstOrDefault().Value; var multiWildcardTopics = multiWildcardTopicsByPublisher.FirstOrDefault().Value; const string ClientId = "Client1"; var logger = new Mockups.TestLogger(); var serverOptions = new MQTTnet.Server.MqttServerOptions(); var eventContainer = new MQTTnet.Server.MqttServerEventContainer(); var retainedMessagesManager = new MqttRetainedMessagesManager(eventContainer, logger); var sessionManager = new MqttClientSessionsManager(serverOptions, retainedMessagesManager, eventContainer, logger); _clientSession = new MQTTnet.Server.MqttSession( ClientId, false, new Dictionary <object, object>(), serverOptions, eventContainer, retainedMessagesManager, sessionManager ); List <string> topicsToSubscribe; switch (selector) { case TopicHashSelector.SingleWildcard: topicsToSubscribe = singleWildcardTopics; break; case TopicHashSelector.MultiWildcard: topicsToSubscribe = multiWildcardTopics; break; default: topicsToSubscribe = topics; break; } foreach (var t in topicsToSubscribe) { var subPacket = new Packets.MqttSubscribePacket(); var filter = new Packets.MqttTopicFilter(); filter.Topic = t; subPacket.TopicFilters.Add(filter); await _clientSession.SubscriptionsManager.Subscribe(subPacket, default(CancellationToken)); } return(topics); }
public void Check_Hash_Bucket_Depth() { Dictionary <string, List <string> > topicsByPublisher; Dictionary <string, List <string> > singleWildcardTopicsByPublisher; Dictionary <string, List <string> > multiWildcardTopicsByPublisher; const int NumPublishers = 5000; const int NumTopicsPerPublisher = 10; TopicGenerator.Generate(NumPublishers, NumTopicsPerPublisher, out topicsByPublisher, out singleWildcardTopicsByPublisher, out multiWildcardTopicsByPublisher); // There will be many 'similar' topics ending with, i.e. "sensor100", "sensor101", ... // Hash bucket depths should remain low. var bucketDepths = new Dictionary <UInt64, int>(); int maxBucketDepth = 0; UInt64 maxBucketDepthHash = 0; var topicsByHash = new Dictionary <UInt64, List <string> >(); foreach (var t in topicsByPublisher) { var topics = t.Value; foreach (var topic in topics) { UInt64 topicHash; UInt64 hashMask; bool hasWildcard; MQTTnet.Server.MqttSubscription.CalculateTopicHash(topic, out topicHash, out hashMask, out hasWildcard); bucketDepths.TryGetValue(topicHash, out var currentValue); ++currentValue; bucketDepths[topicHash] = currentValue; if (currentValue > maxBucketDepth) { maxBucketDepth = currentValue; maxBucketDepthHash = topicHash; } if (!topicsByHash.TryGetValue(topicHash, out var topicList)) { topicList = new List <string>(); topicsByHash.Add(topicHash, topicList); } topicList.Add(topic); } } var maxDepthTopics = topicsByHash[maxBucketDepthHash]; Console.Write("Max bucket depth is " + maxBucketDepth); // for the test case the bucket depth should be less than 100 Assert.IsTrue(maxBucketDepth < 100, "Unexpected high topic hash bucket depth"); }