You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2020/03/20 04:17:28 UTC

[james-project] 05/10: JAMES-3116 Single insert on mailbox counters upon add and remove message

This is an automated email from the ASF dual-hosted git repository.

btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit f51aa1df9443e05bd0d45a56a31853a72be06e71
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Fri Mar 13 21:40:09 2020 +0700

    JAMES-3116 Single insert on mailbox counters upon add and remove message
---
 .../cassandra/mail/CassandraIndexTableHandler.java | 18 ++++----
 .../cassandra/mail/CassandraMailboxCounterDAO.java | 18 ++++++++
 .../mail/CassandraMailboxCounterDAOTest.java       | 51 ++++++++++++++++++++++
 .../task/RecomputeMailboxCountersServiceTest.java  | 10 ++---
 4 files changed, 82 insertions(+), 15 deletions(-)

diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraIndexTableHandler.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraIndexTableHandler.java
index 2232234..8fc3d91 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraIndexTableHandler.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraIndexTableHandler.java
@@ -61,9 +61,8 @@ public class CassandraIndexTableHandler {
         return Flux.mergeDelayError(Queues.XS_BUFFER_SIZE,
                 updateFirstUnseenOnDelete(mailboxId, composedMessageIdWithMetaData.getFlags(), composedMessageIdWithMetaData.getComposedMessageId().getUid()),
                 mailboxRecentDAO.removeFromRecent(mailboxId, composedMessageIdWithMetaData.getComposedMessageId().getUid()),
-                mailboxCounterDAO.decrementCount(mailboxId),
                 deletedMessageDAO.removeDeleted(mailboxId, uid),
-                decrementUnseenOnDelete(mailboxId, composedMessageIdWithMetaData.getFlags()))
+                decrementCountersOnDelete(mailboxId, composedMessageIdWithMetaData.getFlags()))
             .then();
     }
 
@@ -74,8 +73,7 @@ public class CassandraIndexTableHandler {
                 checkDeletedOnAdd(mailboxId, message.createFlags(), message.getUid()),
                 updateFirstUnseenOnAdd(mailboxId, message.createFlags(), message.getUid()),
                 addRecentOnSave(mailboxId, message),
-                incrementUnseenOnSave(mailboxId, flags),
-                mailboxCounterDAO.incrementCount(mailboxId),
+                incrementCountersOnSave(mailboxId, flags),
                 applicableFlagDAO.updateApplicableFlags(mailboxId, ImmutableSet.copyOf(flags.getUserFlags())))
             .then();
     }
@@ -100,18 +98,18 @@ public class CassandraIndexTableHandler {
         }
     }
 
-    private Mono<Void> decrementUnseenOnDelete(CassandraId mailboxId, Flags flags) {
+    private Mono<Void> decrementCountersOnDelete(CassandraId mailboxId, Flags flags) {
         if (flags.contains(Flags.Flag.SEEN)) {
-            return Mono.empty();
+            return mailboxCounterDAO.decrementCount(mailboxId);
         }
-        return mailboxCounterDAO.decrementUnseen(mailboxId);
+        return mailboxCounterDAO.decrementUnseenAndCount(mailboxId);
     }
 
-    private Mono<Void> incrementUnseenOnSave(CassandraId mailboxId, Flags flags) {
+    private Mono<Void> incrementCountersOnSave(CassandraId mailboxId, Flags flags) {
         if (flags.contains(Flags.Flag.SEEN)) {
-            return Mono.empty();
+            return mailboxCounterDAO.incrementCount(mailboxId);
         }
-        return mailboxCounterDAO.incrementUnseen(mailboxId);
+        return mailboxCounterDAO.incrementUnseenAndCount(mailboxId);
     }
 
     private Mono<Void> addRecentOnSave(CassandraId mailboxId, MailboxMessage message) {
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxCounterDAO.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxCounterDAO.java
index 01f2564..02db4a7 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxCounterDAO.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxCounterDAO.java
@@ -54,6 +54,8 @@ public class CassandraMailboxCounterDAO {
     private final PreparedStatement removeToCounters;
     private final PreparedStatement decrementUnseenCountStatement;
     private final PreparedStatement decrementMessageCountStatement;
+    private final PreparedStatement incrementUnseenAndCountStatement;
+    private final PreparedStatement decrementUnseenAndCountStatement;
 
     @Inject
     public CassandraMailboxCounterDAO(Session session) {
@@ -71,6 +73,14 @@ public class CassandraMailboxCounterDAO {
             .where(eq(MAILBOX_ID, bindMarker(MAILBOX_ID))));
         decrementMessageCountStatement = updateMailboxStatement(session, decr(COUNT));
         decrementUnseenCountStatement = updateMailboxStatement(session, decr(UNSEEN));
+        incrementUnseenAndCountStatement =  session.prepare(update(TABLE_NAME)
+            .with(incr(COUNT))
+            .and(incr(UNSEEN))
+            .where(eq(MAILBOX_ID, bindMarker(MAILBOX_ID))));
+        decrementUnseenAndCountStatement = session.prepare(update(TABLE_NAME)
+            .with(decr(COUNT))
+            .and(decr(UNSEEN))
+            .where(eq(MAILBOX_ID, bindMarker(MAILBOX_ID))));
     }
 
     private PreparedStatement createReadStatement(Session session) {
@@ -168,6 +178,14 @@ public class CassandraMailboxCounterDAO {
         return cassandraAsyncExecutor.executeVoid(bindWithMailbox(mailboxId, incrementUnseenCountStatement));
     }
 
+    public Mono<Void> decrementUnseenAndCount(CassandraId mailboxId) {
+        return cassandraAsyncExecutor.executeVoid(bindWithMailbox(mailboxId, decrementUnseenAndCountStatement));
+    }
+
+    public Mono<Void> incrementUnseenAndCount(CassandraId mailboxId) {
+        return cassandraAsyncExecutor.executeVoid(bindWithMailbox(mailboxId, incrementUnseenAndCountStatement));
+    }
+
     private BoundStatement bindWithMailbox(CassandraId mailboxId, PreparedStatement statement) {
         return statement.bind()
             .setUUID(MAILBOX_ID, mailboxId.asUuid());
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxCounterDAOTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxCounterDAOTest.java
index 46451c0..7bc43dc 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxCounterDAOTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxCounterDAOTest.java
@@ -74,6 +74,31 @@ class CassandraMailboxCounterDAOTest {
     }
 
     @Test
+    void incrementUnseenAndCountShouldAddOneWhenAbsent() {
+        testee.incrementUnseenAndCount(MAILBOX_ID).block();
+
+        assertThat(testee.retrieveMailboxCounters(MAILBOX_ID).block())
+            .isEqualTo(MailboxCounters.builder()
+                .mailboxId(MAILBOX_ID)
+                .count(1)
+                .unseen(1)
+                .build());
+    }
+
+    @Test
+    void incrementUnseenAndCountShouldBeApplicableSeveralTimes() {
+        testee.incrementUnseenAndCount(MAILBOX_ID).block();
+        testee.incrementUnseenAndCount(MAILBOX_ID).block();
+
+        assertThat(testee.retrieveMailboxCounters(MAILBOX_ID).block())
+            .isEqualTo(MailboxCounters.builder()
+                .mailboxId(MAILBOX_ID)
+                .count(2)
+                .unseen(2)
+                .build());
+    }
+
+    @Test
     void incrementUnseenShouldAddOneWhenAbsent() {
         testee.incrementUnseen(MAILBOX_ID).block();
 
@@ -182,6 +207,32 @@ class CassandraMailboxCounterDAOTest {
     }
 
     @Test
+    void decrementUnseenAndCountCanLeadToNegativeValue() {
+        testee.decrementUnseenAndCount(MAILBOX_ID).block();
+
+        assertThat(testee.retrieveMailboxCounters(MAILBOX_ID).block())
+            .isEqualTo(MailboxCounters.builder()
+                .mailboxId(MAILBOX_ID)
+                .count(-1)
+                .unseen(-1)
+                .build());
+    }
+
+    @Test
+    void decrementUnseenAndCountShouldRevertIncrementUnseenAndCount() {
+        testee.incrementUnseenAndCount(MAILBOX_ID).block();
+
+        testee.decrementUnseenAndCount(MAILBOX_ID).block();
+
+        assertThat(testee.retrieveMailboxCounters(MAILBOX_ID).block())
+            .isEqualTo(MailboxCounters.builder()
+                .mailboxId(MAILBOX_ID)
+                .count(0)
+                .unseen(0)
+                .build());
+    }
+
+    @Test
     void decrementUnseenCanLeadToNegativeValue() {
         testee.decrementUnseen(MAILBOX_ID).block();
 
diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/task/RecomputeMailboxCountersServiceTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/task/RecomputeMailboxCountersServiceTest.java
index 79b9c94..683e1f7 100644
--- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/task/RecomputeMailboxCountersServiceTest.java
+++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/task/RecomputeMailboxCountersServiceTest.java
@@ -108,7 +108,7 @@ class RecomputeMailboxCountersServiceTest {
         mailboxDAO.save(MAILBOX).block();
         imapUidToMessageIdDAO.insert(METADATA_UNSEEN).block();
         messageIdToImapUidDAO.insert(METADATA_UNSEEN).block();
-        counterDAO.incrementUnseen(CASSANDRA_ID_1).block();
+        counterDAO.incrementUnseenAndCount(CASSANDRA_ID_1).block();
         counterDAO.incrementCount(CASSANDRA_ID_1).block();
 
         testee.recomputeMailboxCounters(new Context()).block();
@@ -122,7 +122,7 @@ class RecomputeMailboxCountersServiceTest {
         mailboxDAO.save(MAILBOX).block();
         imapUidToMessageIdDAO.insert(METADATA_UNSEEN).block();
         messageIdToImapUidDAO.insert(METADATA_SEEN).block();
-        counterDAO.incrementUnseen(CASSANDRA_ID_1).block();
+        counterDAO.incrementUnseenAndCount(CASSANDRA_ID_1).block();
         counterDAO.incrementCount(CASSANDRA_ID_1).block();
 
         testee.recomputeMailboxCounters(new Context()).block();
@@ -147,7 +147,7 @@ class RecomputeMailboxCountersServiceTest {
     void recomputeMailboxCountersShouldReturnCompletedWhenOrphanMailboxRegistration() {
         mailboxDAO.save(MAILBOX).block();
         imapUidToMessageIdDAO.insert(METADATA_UNSEEN).block();
-        counterDAO.incrementUnseen(CASSANDRA_ID_1).block();
+        counterDAO.incrementUnseenAndCount(CASSANDRA_ID_1).block();
         counterDAO.incrementCount(CASSANDRA_ID_1).block();
 
         testee.recomputeMailboxCounters(new Context()).block();
@@ -160,7 +160,7 @@ class RecomputeMailboxCountersServiceTest {
     void recomputeMailboxCountersShouldReturnCompletedWhenMailboxListReferenceIsMissing() {
         mailboxDAO.save(MAILBOX).block();
         messageIdToImapUidDAO.insert(METADATA_UNSEEN).block();
-        counterDAO.incrementUnseen(CASSANDRA_ID_1).block();
+        counterDAO.incrementUnseenAndCount(CASSANDRA_ID_1).block();
         counterDAO.incrementCount(CASSANDRA_ID_1).block();
 
         testee.recomputeMailboxCounters(new Context()).block();
@@ -184,7 +184,7 @@ class RecomputeMailboxCountersServiceTest {
         mailboxDAO.save(MAILBOX).block();
         imapUidToMessageIdDAO.insert(METADATA_UNSEEN).block();
         messageIdToImapUidDAO.insert(METADATA_UNSEEN).block();
-        counterDAO.incrementUnseen(CASSANDRA_ID_1).block();
+        counterDAO.incrementUnseenAndCount(CASSANDRA_ID_1).block();
         counterDAO.incrementCount(CASSANDRA_ID_1).block();
 
         testee.recomputeMailboxCounters(new Context()).block();


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org