On Thu, Nov 29, 2001 at 01:21:33PM +0300, Alexander V. Lukyanov wrote:
> Ok, I have applied the case insensity patch. BTW, LsCache::Dump is missing.

Oops.  I got overzealous in removing the incomplete path-type-caching
stuff in LsCache.  It's in the middle of those mods, so I'll just dump
the function:

void LsCache::Dump()
{
   for(LsCache *scan=chain; scan; scan=scan->next)
   {
      printf("%s:\n", scan->loc->GetConnectURL());
      printf("Data:\n");
      if(!scan->data) printf("(empty)");
      else fwrite(scan->data, scan->data_len, 1, stdout);
      printf("\nArg: %s\n", *scan->arg? scan->arg:"(none)");
   }
}

I think there's an extranneous Do() declared in class LsCache, by the
way.

I've also attached a patch to ColumnOutput.cc to binary search for a
column config.  I don't recommend this be applied unless it can be
simplified.  The speed gain for a 10k directory with 4-character files
in a wide screen--worst case--was 100ms to 40ms or so for that call on
this system; that's not a bad gain (would matter on slow systems), but
it complicates the function too much.  I'm mostly posting it to make it
available, since I'm rolling back my ColumnOutput.cc.

-- 
Glenn Maynard
Index: ColumnOutput.cc
===================================================================
RCS file: /home/lav/cvsroot/lftp/src/ColumnOutput.cc,v
retrieving revision 1.9
diff -u -r1.9 ColumnOutput.cc
--- ColumnOutput.cc     2001/11/13 16:26:41     1.9
+++ ColumnOutput.cc     2001/11/29 18:27:34
@@ -27,9 +27,10 @@
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
-
+#include <assert.h>
 #include <mbswidth.h>
 
+#include "xalloca.h"
 #include "SMTask.h"
 #include "ColumnOutput.h"
 #include "ResMgr.h"
@@ -100,23 +101,37 @@
    }
 }
 
-void ColumnOutput::get_print_info(unsigned width, int *&col_arr, int *&ws_arr, int 
&cols) const
+void ColumnOutput::get_print_info(unsigned width, int *&out_col_arr, int 
+*&out_ws_arr, int &cols) const
 {
    /* Maximum number of columns ever possible for this display.  */
    int max_idx = width / MIN_COLUMN_WIDTH;
    if (max_idx == 0) max_idx = 1;
+
+   out_col_arr = (int *) xmalloc (max_idx * sizeof (int));
+   out_ws_arr = (int *) xmalloc (max_idx * sizeof (int));
+
+   int *col_arr = (int *) alloca (max_idx * sizeof (int));
+   int *ws_arr = (int *) alloca (max_idx * sizeof (int));
+
 
-   col_arr = (int *) xmalloc (max_idx * sizeof (int));
-   ws_arr = (int *) xmalloc (max_idx * sizeof (int));
+   /* Compute the maximum number of possible columns:
+    * lower and upper bounds on possible number of columns;
+    * lower must always be a valid column count
+    */
+   int lower = 1;
 
    /* Normally the maximum number of columns is determined by the
     * screen width.  But if few files are available this might limit it
     * as well. */
-   int max_cols = max_idx > lst_cnt ? lst_cnt : max_idx;
-   if(max_cols < 1) max_cols = 1;
-
-   /* Compute the maximum number of possible columns.  */
-   for (cols = max_cols; cols >= 1; cols--) {
+   int upper = max_idx > lst_cnt ? lst_cnt : max_idx;
+   if(upper < 1) upper = 1;
+   
+   /* test at the end; we need to go through all this at least once
+    * in case lower == upper == 1. */
+   do {
+      /* average of lower and upper, rounded up */
+      cols = (lower + upper + 1) / 2;
+           
       for (int j = 0; j < max_idx; ++j) {
         col_arr[j] = MIN_COLUMN_WIDTH;
         ws_arr[j] = 99999999;
@@ -146,12 +161,20 @@
         line_len += (real_length - col_arr[idx]);
         col_arr[idx] = real_length;
       }
-      if(line_len < width)
-        break; /* found it */
-   }
-   if(cols == 0) cols = 1;
-
+      if(width == 0 || line_len < width) {
+        /* this will fit (or we've been forced to 1 column); make it
+         * the new lower bound */
+        lower = cols;
+        /* these will be our results unless we find a better match: */
+        memcpy(out_col_arr, col_arr, max_idx * sizeof (int));
+        memcpy(out_ws_arr, ws_arr, max_idx * sizeof (int));
+      }
+      
+      if(line_len >= width)
+        upper = cols-1; /* this won't fit; new upper bound is at most cols-1 */
+   } while(lower < upper);
 
+   cols = lower;
 }
 
 void ColumnOutput::print(Buffer *o, unsigned width, bool color) const
@@ -180,6 +203,7 @@
       while (1) {
         lst[filesno]->print(o, color, ws_arr[col], color_pref, color_suf, 
color_reset);
         int name_length = lst[filesno]->width() - ws_arr[col];
+        assert(name_length >= 0);
         int max_name_length = col_arr[col++];
 
         filesno += rows;

Reply via email to