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;