From e1bff7958adbf7780a70fd6e687e344edf11fdcc Mon Sep 17 00:00:00 2001
From: Kinsey Moore <kmoore@digium.com>
Date: Fri, 31 May 2013 12:27:29 +0000
Subject: [PATCH] Add snapshot cache that indexes by channel name

This adds a new channel snapshot cache in parallel to the existing
cache; the difference being that it indexes the channel snapshots by
channel name instead of channel uniqueid.

Review: https://reviewboard.asterisk.org/r/2576


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@390249 65c4cc65-6c06-0410-ace0-fbb531ad65f3
---
 include/asterisk/stasis_channels.h | 21 +++++++++++++++
 main/stasis_channels.c             | 42 ++++++++++++++++++++++++++++++
 2 files changed, 63 insertions(+)

diff --git a/include/asterisk/stasis_channels.h b/include/asterisk/stasis_channels.h
index e521e05eb8..64224c04f0 100644
--- a/include/asterisk/stasis_channels.h
+++ b/include/asterisk/stasis_channels.h
@@ -102,6 +102,15 @@ struct stasis_topic *ast_channel_topic_all(void);
  */
 struct stasis_caching_topic *ast_channel_topic_all_cached(void);
 
+/*!
+ * \since 12
+ * \brief A caching topic which caches \ref ast_channel_snapshot messages from
+ * ast_channel_events_all(void) and indexes them by name.
+ *
+ * \retval Topic for all channel events.
+ */
+struct stasis_caching_topic *ast_channel_topic_all_cached_by_name(void);
+
 /*!
  * \since 12
  * \brief Message type for \ref ast_channel_snapshot.
@@ -135,6 +144,18 @@ struct ast_channel_snapshot *ast_channel_snapshot_create(
  */
 struct ast_channel_snapshot *ast_channel_snapshot_get_latest(const char *uniqueid);
 
+/*!
+ * \since 12
+ * \brief Obtain the latest \ref ast_channel_snapshot from the \ref stasis cache. This is
+ * an ao2 object, so use \ref ao2_cleanup() to deallocate.
+ *
+ * \param name The channel's name
+ *
+ * \retval A \ref ast_channel_snapshot on success
+ * \retval NULL on error
+ */
+struct ast_channel_snapshot *ast_channel_snapshot_get_latest_by_name(const char *name);
+
 /*!
  * \since 12
  * \brief Creates a \ref ast_channel_blob message.
diff --git a/main/stasis_channels.c b/main/stasis_channels.c
index c08bbd99fd..ae253ddca8 100644
--- a/main/stasis_channels.c
+++ b/main/stasis_channels.c
@@ -66,6 +66,9 @@ struct stasis_topic *channel_topic_all;
 /*! \brief Caching topic for all channels */
 struct stasis_caching_topic *channel_topic_all_cached;
 
+/*! \brief Caching topic for all channels indexed by name */
+struct stasis_caching_topic *channel_topic_all_cached_by_name;
+
 struct stasis_topic *ast_channel_topic_all(void)
 {
 	return channel_topic_all;
@@ -86,6 +89,21 @@ static const char *channel_snapshot_get_id(struct stasis_message *message)
 	return snapshot->uniqueid;
 }
 
+struct stasis_caching_topic *ast_channel_topic_all_cached_by_name(void)
+{
+	return channel_topic_all_cached_by_name;
+}
+
+static const char *channel_snapshot_get_name(struct stasis_message *message)
+{
+	struct ast_channel_snapshot *snapshot;
+	if (ast_channel_snapshot_type() != stasis_message_type(message)) {
+		return NULL;
+	}
+	snapshot = stasis_message_data(message);
+	return snapshot->name;
+}
+
 /*! \internal \brief Hash function for \ref ast_channel_snapshot objects */
 static int channel_snapshot_hash_cb(const void *obj, const int flags)
 {
@@ -366,6 +384,28 @@ struct ast_channel_snapshot *ast_channel_snapshot_get_latest(const char *uniquei
 	return snapshot;
 }
 
+struct ast_channel_snapshot *ast_channel_snapshot_get_latest_by_name(const char *name)
+{
+	RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
+	struct ast_channel_snapshot *snapshot;
+
+	ast_assert(!ast_strlen_zero(name));
+
+	message = stasis_cache_get(ast_channel_topic_all_cached_by_name(),
+			ast_channel_snapshot_type(),
+			name);
+	if (!message) {
+		return NULL;
+	}
+
+	snapshot = stasis_message_data(message);
+	if (!snapshot) {
+		return NULL;
+	}
+	ao2_ref(snapshot, +1);
+	return snapshot;
+}
+
 static void channel_role_snapshot_dtor(void *obj)
 {
 	struct channel_role_snapshot *role_snapshot = obj;
@@ -578,6 +618,7 @@ int ast_channel_snapshot_caller_id_equal(
 static void stasis_channels_cleanup(void)
 {
 	channel_topic_all_cached = stasis_caching_unsubscribe_and_join(channel_topic_all_cached);
+	channel_topic_all_cached_by_name = stasis_caching_unsubscribe_and_join(channel_topic_all_cached_by_name);
 	ao2_cleanup(channel_topic_all);
 	channel_topic_all = NULL;
 	STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_snapshot_type);
@@ -623,4 +664,5 @@ void ast_stasis_channels_init(void)
 
 	channel_topic_all = stasis_topic_create("ast_channel_topic_all");
 	channel_topic_all_cached = stasis_caching_topic_create(channel_topic_all, channel_snapshot_get_id);
+	channel_topic_all_cached_by_name = stasis_caching_topic_create(channel_topic_all, channel_snapshot_get_name);
 }
-- 
GitLab