changeset 1141:5be2408a6534

Add option "max_history_blocks"
author Mikael Berthe <mikael@lilotux.net>
date Tue, 06 Feb 2007 00:21:42 +0100
parents 800bb1e9019c
children 0e27177882c7
files mcabber/mcabberrc.example mcabber/src/hbuf.c mcabber/src/hbuf.h mcabber/src/histolog.c mcabber/src/screen.c mcabber/src/settings.c mcabber/src/settings.h
diffstat 7 files changed, 78 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/mcabber/mcabberrc.example	Sun Feb 04 18:49:47 2007 +0100
+++ b/mcabber/mcabberrc.example	Tue Feb 06 00:21:42 2007 +0100
@@ -98,7 +98,8 @@
 # Defaults for logging, load_logs are 0 (disabled)
 # Note: the logging directory must exist if you enable logging, mcabber
 #       will not create it.
-# Note: these options, except 'max_history_age', are used at startup time.
+# Note: these options, except 'max_history_age' and 'max_history_blocks',
+# are used at startup time.
 #set logging = 1
 #set load_logs = 1
 #set logging_dir = /home/mikael/.mcabber/histo/
@@ -115,6 +116,10 @@
 # Default = 0 (disabled -- everything is loaded)
 # Note: this option is only used when reading history files, not later.
 #set max_history_age = 0
+#
+# You can specify a maximum number of data blocks per buffer (1 block contains
+# about 8kB).  The default is 0 (unlimited).  If set, this value must be > 2.
+#set max_history_blocks = 8
 
 # IQ settings
 # Set iq_version_hide_os to 1 if you do not want to allow people to retrieve
--- a/mcabber/src/hbuf.c	Sun Feb 04 18:49:47 2007 +0100
+++ b/mcabber/src/hbuf.c	Tue Feb 06 00:21:42 2007 +0100
@@ -107,18 +107,20 @@
   }
 }
 
-//  hbuf_add_line(p_hbuf, text, prefix_flags, width)
+//  hbuf_add_line(p_hbuf, text, prefix_flags, width, maxhbufblocks)
 // Add a line to the given buffer.  If width is not null, then lines are
 // wrapped at this length.
+// maxhbufblocks is the maximum number of hbuf blocks we can allocate.  If
+// null, there is no limit.  If non-null, it should be >= 2.
 //
 // Note 1: Splitting according to width won't work if there are tabs; they
 //         should be expanded before.
 // Note 2: width does not include the ending \0.
 void hbuf_add_line(GList **p_hbuf, const char *text, time_t timestamp,
-        guint prefix_flags, guint width)
+        guint prefix_flags, guint width, guint maxhbufblocks)
 {
   GList *curr_elt;
-  char *line, *end;
+  char *line;
   hbuf_block *hbuf_block_elt;
 
   if (!text) return;
@@ -149,7 +151,52 @@
   }
   if (hbuf_block_elt->ptr + strlen(text) >= hbuf_block_elt->ptr_end_alloc) {
     // Too long for the current allocated bloc, we need another one
-    hbuf_block_elt->ptr  = g_new0(char, HBB_BLOCKSIZE);
+    if (!maxhbufblocks) {
+      // No limit, let's allocate a new block
+      hbuf_block_elt->ptr  = g_new0(char, HBB_BLOCKSIZE);
+    } else {
+      GList *hbuf_head, *hbuf_elt;
+      hbuf_block *hbuf_b_elt;
+      guint n = 0;
+      hbuf_head = g_list_first(*p_hbuf);
+      // We need at least 2 allocated blocks
+      if (maxhbufblocks == 1)
+        maxhbufblocks = 2;
+      // Let's count the number of allocated areas
+      for (hbuf_elt = hbuf_head; hbuf_elt; hbuf_elt = g_list_next(hbuf_elt)) {
+        hbuf_b_elt = (hbuf_block*)(hbuf_elt->data);
+        if (hbuf_b_elt->flags & HBB_FLAG_ALLOC)
+          n++;
+      }
+      // If we can't allocate a new area, reuse the previous block(s)
+      if (n < maxhbufblocks) {
+        hbuf_block_elt->ptr  = g_new0(char, HBB_BLOCKSIZE);
+      } else {
+        // Let's use an old block, and free the extra blocks if needed
+        char *allocated_block = NULL;
+        while (n >= maxhbufblocks) {
+          /* --- */
+          int start_of_block = 1;
+          for (hbuf_elt = hbuf_head; hbuf_elt; hbuf_elt = hbuf_head) {
+            hbuf_b_elt = (hbuf_block*)(hbuf_elt->data);
+            if (hbuf_b_elt->flags & HBB_FLAG_ALLOC) {
+              if (start_of_block-- == 0)
+                break;
+              if (n == maxhbufblocks)
+                allocated_block = hbuf_b_elt->ptr;
+              else
+                g_free(hbuf_b_elt->ptr);
+            }
+            g_free(hbuf_b_elt);
+            hbuf_head = *p_hbuf = g_list_delete_link(hbuf_head, hbuf_elt);
+          }
+          n--;
+          /* --- */
+        }
+        memset(allocated_block, 0, HBB_BLOCKSIZE);
+        hbuf_block_elt->ptr = allocated_block;
+      }
+    }
     hbuf_block_elt->flags  = HBB_FLAG_ALLOC | HBB_FLAG_PERSISTENT;
     hbuf_block_elt->ptr_end_alloc = hbuf_block_elt->ptr + HBB_BLOCKSIZE;
   }
@@ -158,7 +205,6 @@
   // Ok, now we can copy the text..
   strcpy(line, text);
   hbuf_block_elt->ptr_end = line + strlen(line) + 1;
-  end = hbuf_block_elt->ptr_end;
 
   curr_elt = g_list_last(*p_hbuf);
 
--- a/mcabber/src/hbuf.h	Sun Feb 04 18:49:47 2007 +0100
+++ b/mcabber/src/hbuf.h	Tue Feb 06 00:21:42 2007 +0100
@@ -33,7 +33,7 @@
 } hbb_line;
 
 void hbuf_add_line(GList **p_hbuf, const char *text, time_t timestamp,
-        guint prefix_flags, guint width);
+        guint prefix_flags, guint width, guint maxhbufblocks);
 void hbuf_free(GList **p_hbuf);
 void hbuf_rebuild(GList **p_hbuf, unsigned int width);
 GList *hbuf_previous_persistent(GList *l_line);
--- a/mcabber/src/histolog.c	Sun Feb 04 18:49:47 2007 +0100
+++ b/mcabber/src/histolog.c	Tue Feb 06 00:21:42 2007 +0100
@@ -135,6 +135,7 @@
   guint err = 0;
   guint ln = 0; // line number
   time_t starttime;
+  int max_num_of_blocks;
 
   if (!FileLoadLogs)
     return;
@@ -165,6 +166,8 @@
       scr_LogPrint(LPRINT_LOGNORM, "Reading <%s> history file...", bjid);
   }
 
+  max_num_of_blocks = get_max_history_blocks();
+
   starttime = 0L;
   if (settings_opt_get_int("max_history_age") > 0) {
     int maxdays = settings_opt_get_int("max_history_age");
@@ -252,7 +255,8 @@
       converted = from_utf8(&data[dataoffset+1]);
       if (converted) {
         xtext = ut_expand_tabs(converted); // Expand tabs
-        hbuf_add_line(p_buddyhbuf, xtext, timestamp, prefix_flags, width);
+        hbuf_add_line(p_buddyhbuf, xtext, timestamp, prefix_flags, width,
+                      max_num_of_blocks);
         if (xtext != converted)
           g_free(xtext);
         g_free(converted);
--- a/mcabber/src/screen.c	Sun Feb 04 18:49:47 2007 +0100
+++ b/mcabber/src/screen.c	Tue Feb 06 00:21:42 2007 +0100
@@ -395,7 +395,7 @@
       printf("%s\n", buffer_locale);
       // ncurses are not initialized yet, so we call directly hbuf routine
       hbuf_add_line(&statushbuf, buf_specialwindow, timestamp,
-        HBB_PREFIX_SPECIAL, 0);
+        HBB_PREFIX_SPECIAL, 0, 0);
     }
 
     g_free(convbuf1);
@@ -691,7 +691,8 @@
 
   text_locale = from_utf8(text);
   hbuf_add_line(&win_entry->hbuf, text_locale, timestamp, prefix_flags,
-                maxX - Roster_Width - PREFIX_WIDTH);
+                maxX - Roster_Width - PREFIX_WIDTH,
+                get_max_history_blocks());
   g_free(text_locale);
 
   if (win_entry->cleared) {
--- a/mcabber/src/settings.c	Sun Feb 04 18:49:47 2007 +0100
+++ b/mcabber/src/settings.c	Tue Feb 06 00:21:42 2007 +0100
@@ -428,4 +428,14 @@
   return NULL;
 }
 
+guint get_max_history_blocks(void)
+{
+  int max_num_of_blocks = settings_opt_get_int("max_history_blocks");
+  if (max_num_of_blocks < 0)
+    max_num_of_blocks = 0;
+  else if (max_num_of_blocks == 1)
+    max_num_of_blocks = 2;
+  return (guint)max_num_of_blocks;
+}
+
 /* vim: set expandtab cindent cinoptions=>2\:2(0:  For Vim users... */
--- a/mcabber/src/settings.h	Sun Feb 04 18:49:47 2007 +0100
+++ b/mcabber/src/settings.h	Tue Feb 06 00:21:42 2007 +0100
@@ -40,6 +40,8 @@
 void    settings_pgp_setkeyid(const char *bjid, const char *keyid);
 const char *settings_pgp_getkeyid(const char *bjid);
 
+guint get_max_history_blocks(void);
+
 char *default_muc_nickname(void);
 
 const gchar *isbound(int key);