static int client_input_status_overview(struct doveadm_connection *client)
{
- struct replicator_user *const *users;
+ struct replicator_queue_iter *iter;
+ struct replicator_user *user;
enum replication_priority priority;
unsigned int pending_counts[REPLICATION_PRIORITY_SYNC+1];
- unsigned int i, count, next_secs, pending_failed_count;
+ unsigned int user_count, next_secs, pending_failed_count;
unsigned int pending_full_resync_count, waiting_failed_count;
string_t *str = t_str_new(256);
pending_failed_count = 0; waiting_failed_count = 0;
pending_full_resync_count = 0;
- users = replicator_queue_get_users(client->queue, &count);
- for (i = 0; i < count; i++) {
- if (users[i]->priority != REPLICATION_PRIORITY_NONE)
- pending_counts[users[i]->priority]++;
+ user_count = 0;
+ iter = replicator_queue_iter_init(client->queue);
+ while ((user = replicator_queue_iter_next(iter)) != NULL) {
+ if (user->priority != REPLICATION_PRIORITY_NONE)
+ pending_counts[user->priority]++;
else if (replicator_queue_want_sync_now(client->queue,
- users[i], &next_secs)) {
- if (users[i]->last_sync_failed)
+ user, &next_secs)) {
+ if (user->last_sync_failed)
pending_failed_count++;
else
pending_full_resync_count++;
} else {
- if (users[i]->last_sync_failed)
+ if (user->last_sync_failed)
waiting_failed_count++;
}
+ user_count++;
}
+ replicator_queue_iter_deinit(&iter);
for (priority = REPLICATION_PRIORITY_SYNC; priority > 0; priority--) {
str_printfa(str, "Queued '%s' requests\t%u\n",
pending_full_resync_count);
str_printfa(str, "Waiting 'failed' requests\t%u\n",
waiting_failed_count);
- str_printfa(str, "Total number of known users\t%u\n", count);
+ str_printfa(str, "Total number of known users\t%u\n", user_count);
str_append_c(str, '\n');
o_stream_send(client->conn.output, str_data(str), str_len(str));
return 0;
static int
client_input_status(struct doveadm_connection *client, const char *const *args)
{
- struct replicator_user *const *users, *user;
- unsigned int i, count;
+ struct replicator_queue_iter *iter;
+ struct replicator_user *user;
const char *mask = args[0];
string_t *str = t_str_new(128);
if (mask == NULL)
return client_input_status_overview(client);
- users = replicator_queue_get_users(client->queue, &count);
- for (i = 0; i < count; i++) {
- user = users[i];
+ iter = replicator_queue_iter_init(client->queue);
+ while ((user = replicator_queue_iter_next(iter)) != NULL) {
if (!wildcard_match(user->username, mask))
continue;
user->last_sync_failed);
o_stream_send(client->conn.output, str_data(str), str_len(str));
}
+ replicator_queue_iter_deinit(&iter);
o_stream_send(client->conn.output, "\n", 1);
return 0;
}
static int
client_input_replicate(struct doveadm_connection *client, const char *const *args)
{
- struct replicator_user *const *queue_users, **users_dup;
- unsigned int i, count, match_count;
+ struct replicator_queue_iter *iter;
+ struct replicator_user *user;
const char *usermask;
enum replication_priority priority;
+ unsigned int match_count;
/* <priority> <username>|<mask> */
if (str_array_length(args) != 2) {
return 0;
}
- queue_users = replicator_queue_get_users(client->queue, &count);
- users_dup = i_new(struct replicator_user *, count+1);
- for (i = match_count = 0; i < count; i++) {
- if (wildcard_match(queue_users[i]->username, usermask))
- users_dup[match_count++] = queue_users[i];
- }
- for (i = 0; i < match_count; i++) {
- replicator_queue_add(client->queue, users_dup[i]->username,
- priority);
+ match_count = 0;
+ iter = replicator_queue_iter_init(client->queue);
+ while ((user = replicator_queue_iter_next(iter)) != NULL) {
+ if (!wildcard_match(user->username, usermask))
+ continue;
+ replicator_queue_add(client->queue, user->username, priority);
+ match_count++;
}
+ replicator_queue_iter_deinit(&iter);
o_stream_send_str(client->conn.output,
t_strdup_printf("+%u\n", match_count));
return 0;
void *change_context;
};
+struct replicator_queue_iter {
+ struct replicator_queue *queue;
+ struct hash_iterate_context *iter;
+};
+
static int user_priority_cmp(const void *p1, const void *p2)
{
const struct replicator_user *user1 = p1, *user2 = p2;
int replicator_queue_export(struct replicator_queue *queue, const char *path)
{
+ struct replicator_queue_iter *iter;
+ struct replicator_user *user;
struct ostream *output;
- struct priorityq_item *const *items;
- unsigned int i, count;
string_t *str;
int fd, ret = 0;
o_stream_cork(output);
str = t_str_new(128);
- items = priorityq_items(queue->user_queue);
- count = priorityq_count(queue->user_queue);
- for (i = 0; i < count; i++) {
- struct replicator_user *user =
- (struct replicator_user *)items[i];
-
+ iter = replicator_queue_iter_init(queue);
+ while ((user = replicator_queue_iter_next(iter)) != NULL) {
str_truncate(str, 0);
replicator_queue_export_user(user, str);
if (o_stream_send(output, str_data(str), str_len(str)) < 0)
break;
}
+ replicator_queue_iter_deinit(&iter);
if (o_stream_nfinish(output) < 0) {
i_error("write(%s) failed: %m", path);
ret = -1;
return ret;
}
-struct replicator_user *const *
-replicator_queue_get_users(struct replicator_queue *queue,
- unsigned int *count_r)
+struct replicator_queue_iter *
+replicator_queue_iter_init(struct replicator_queue *queue)
{
- struct priorityq_item *const *items =
- priorityq_items(queue->user_queue);
+ struct replicator_queue_iter *iter;
+
+ iter = i_new(struct replicator_queue_iter, 1);
+ iter->queue = queue;
+ iter->iter = hash_table_iterate_init(queue->user_hash);
+ return iter;
+}
+
+struct replicator_user *
+replicator_queue_iter_next(struct replicator_queue_iter *iter)
+{
+ struct replicator_user *user;
+ char *username;
+
+ if (!hash_table_iterate(iter->iter, iter->queue->user_hash,
+ &username, &user))
+ return NULL;
+ return user;
+}
+
+void replicator_queue_iter_deinit(struct replicator_queue_iter **_iter)
+{
+ struct replicator_queue_iter *iter = *_iter;
+
+ *_iter = NULL;
- *count_r = priorityq_count(queue->user_queue);
- return (void *)items;
+ hash_table_iterate_deinit(&iter->iter);
+ i_free(iter);
}