Perform RichString operations by hand.

Avoid unnecessary operations when processing entries on ProcessList.
This commit is contained in:
Hisham Muhammad 2006-07-12 01:16:03 +00:00
parent e46f1426b9
commit dbe2670b69
13 changed files with 64 additions and 92 deletions

View File

@ -81,7 +81,7 @@ void CPUMeter_setValues(Meter* this, char* buffer, int size) {
void CPUMeter_display(Object* cast, RichString* out) { void CPUMeter_display(Object* cast, RichString* out) {
char buffer[50]; char buffer[50];
Meter* this = (Meter*)cast; Meter* this = (Meter*)cast;
RichString_prune(out); RichString_init(out);
sprintf(buffer, "%5.1f%% ", this->values[1]); sprintf(buffer, "%5.1f%% ", this->values[1]);
RichString_append(out, CRT_colors[METER_TEXT], ":"); RichString_append(out, CRT_colors[METER_TEXT], ":");
RichString_append(out, CRT_colors[CPU_NORMAL], buffer); RichString_append(out, CRT_colors[CPU_NORMAL], buffer);

View File

@ -16,7 +16,6 @@ in the source distribution for its full text.
typedef struct Hashtable_ Hashtable; typedef struct Hashtable_ Hashtable;
typedef void(*Hashtable_PairFunction)(int, void*, void*); typedef void(*Hashtable_PairFunction)(int, void*, void*);
typedef int(*Hashtable_HashAlgorithm)(Hashtable*, int);
typedef struct HashtableItem { typedef struct HashtableItem {
int key; int key;
@ -28,7 +27,6 @@ struct Hashtable_ {
int size; int size;
HashtableItem** buckets; HashtableItem** buckets;
int items; int items;
Hashtable_HashAlgorithm hashAlgorithm;
bool owner; bool owner;
}; };
}*/ }*/
@ -49,15 +47,10 @@ Hashtable* Hashtable_new(int size, bool owner) {
this = (Hashtable*) malloc(sizeof(Hashtable)); this = (Hashtable*) malloc(sizeof(Hashtable));
this->size = size; this->size = size;
this->buckets = (HashtableItem**) calloc(sizeof(HashtableItem*), size); this->buckets = (HashtableItem**) calloc(sizeof(HashtableItem*), size);
this->hashAlgorithm = Hashtable_hashAlgorithm;
this->owner = owner; this->owner = owner;
return this; return this;
} }
int Hashtable_hashAlgorithm(Hashtable* this, int key) {
return key % this->size;
}
void Hashtable_delete(Hashtable* this) { void Hashtable_delete(Hashtable* this) {
for (int i = 0; i < this->size; i++) { for (int i = 0; i < this->size; i++) {
HashtableItem* walk = this->buckets[i]; HashtableItem* walk = this->buckets[i];
@ -78,7 +71,7 @@ inline int Hashtable_size(Hashtable* this) {
} }
void Hashtable_put(Hashtable* this, int key, void* value) { void Hashtable_put(Hashtable* this, int key, void* value) {
int index = this->hashAlgorithm(this, key); int index = key % this->size;
HashtableItem** bucketPtr = &(this->buckets[index]); HashtableItem** bucketPtr = &(this->buckets[index]);
while (true) while (true)
if (*bucketPtr == NULL) { if (*bucketPtr == NULL) {
@ -95,7 +88,7 @@ void Hashtable_put(Hashtable* this, int key, void* value) {
} }
void* Hashtable_remove(Hashtable* this, int key) { void* Hashtable_remove(Hashtable* this, int key) {
int index = this->hashAlgorithm(this, key); int index = key % this->size;
HashtableItem** bucketPtr = &(this->buckets[index]); HashtableItem** bucketPtr = &(this->buckets[index]);
while (true) while (true)
if (*bucketPtr == NULL) { if (*bucketPtr == NULL) {
@ -118,7 +111,7 @@ void* Hashtable_remove(Hashtable* this, int key) {
} }
//#include <stdio.h> //#include <stdio.h>
inline void* Hashtable_get(Hashtable* this, int key) { inline void* Hashtable_get(Hashtable* this, int key) {
int index = this->hashAlgorithm(this, key); int index = key % this->size;
HashtableItem* bucketPtr = this->buckets[index]; HashtableItem* bucketPtr = this->buckets[index];
// fprintf(stderr, "%d -> %d\n", key, index); // fprintf(stderr, "%d -> %d\n", key, index);
while (true) { while (true) {

View File

@ -18,7 +18,6 @@ in the source distribution for its full text.
typedef struct Hashtable_ Hashtable; typedef struct Hashtable_ Hashtable;
typedef void(*Hashtable_PairFunction)(int, void*, void*); typedef void(*Hashtable_PairFunction)(int, void*, void*);
typedef int(*Hashtable_HashAlgorithm)(Hashtable*, int);
typedef struct HashtableItem { typedef struct HashtableItem {
int key; int key;
@ -30,7 +29,6 @@ struct Hashtable_ {
int size; int size;
HashtableItem** buckets; HashtableItem** buckets;
int items; int items;
Hashtable_HashAlgorithm hashAlgorithm;
bool owner; bool owner;
}; };
@ -38,8 +36,6 @@ HashtableItem* HashtableItem_new(int key, void* value);
Hashtable* Hashtable_new(int size, bool owner); Hashtable* Hashtable_new(int size, bool owner);
int Hashtable_hashAlgorithm(Hashtable* this, int key);
void Hashtable_delete(Hashtable* this); void Hashtable_delete(Hashtable* this);
inline int Hashtable_size(Hashtable* this); inline int Hashtable_size(Hashtable* this);

View File

@ -60,7 +60,7 @@ void LoadAverageMeter_setValues(Meter* this, char* buffer, int size) {
void LoadAverageMeter_display(Object* cast, RichString* out) { void LoadAverageMeter_display(Object* cast, RichString* out) {
Meter* this = (Meter*)cast; Meter* this = (Meter*)cast;
char buffer[20]; char buffer[20];
RichString_prune(out); RichString_init(out);
sprintf(buffer, "%.2f ", this->values[2]); sprintf(buffer, "%.2f ", this->values[2]);
RichString_append(out, CRT_colors[LOAD_AVERAGE_FIFTEEN], buffer); RichString_append(out, CRT_colors[LOAD_AVERAGE_FIFTEEN], buffer);
sprintf(buffer, "%.2f ", this->values[1]); sprintf(buffer, "%.2f ", this->values[1]);
@ -81,7 +81,7 @@ void LoadMeter_setValues(Meter* this, char* buffer, int size) {
void LoadMeter_display(Object* cast, RichString* out) { void LoadMeter_display(Object* cast, RichString* out) {
Meter* this = (Meter*)cast; Meter* this = (Meter*)cast;
char buffer[20]; char buffer[20];
RichString_prune(out); RichString_init(out);
sprintf(buffer, "%.2f ", ((Meter*)this)->values[0]); sprintf(buffer, "%.2f ", ((Meter*)this)->values[0]);
RichString_append(out, CRT_colors[LOAD], buffer); RichString_append(out, CRT_colors[LOAD], buffer);
} }

View File

@ -55,7 +55,7 @@ void MemoryMeter_display(Object* cast, RichString* out) {
long int usedMem = this->values[0] / div; long int usedMem = this->values[0] / div;
long int buffersMem = this->values[1] / div; long int buffersMem = this->values[1] / div;
long int cachedMem = this->values[2] / div; long int cachedMem = this->values[2] / div;
RichString_prune(out); RichString_init(out);
RichString_append(out, CRT_colors[METER_TEXT], ":"); RichString_append(out, CRT_colors[METER_TEXT], ":");
sprintf(buffer, format, totalMem); sprintf(buffer, format, totalMem);
RichString_append(out, CRT_colors[METER_VALUE], buffer); RichString_append(out, CRT_colors[METER_VALUE], buffer);

View File

@ -206,7 +206,7 @@ static inline void Meter_displayToStringBuffer(Meter* this, char* buffer) {
if (display) { if (display) {
display((Object*)this, &Meter_stringBuffer); display((Object*)this, &Meter_stringBuffer);
} else { } else {
RichString_prune(&Meter_stringBuffer); RichString_initVal(Meter_stringBuffer);
RichString_append(&Meter_stringBuffer, CRT_colors[type->attributes[0]], buffer); RichString_append(&Meter_stringBuffer, CRT_colors[type->attributes[0]], buffer);
} }
} }

13
Panel.c
View File

@ -96,16 +96,12 @@ void Panel_init(Panel* this, int x, int y, int w, int h, char* type, bool owner)
void Panel_done(Panel* this) { void Panel_done(Panel* this) {
assert (this != NULL); assert (this != NULL);
RichString_delete(this->header);
Vector_delete(this->items); Vector_delete(this->items);
} }
inline void Panel_setRichHeader(Panel* this, RichString header) { inline void Panel_setRichHeader(Panel* this, RichString header) {
assert (this != NULL); assert (this != NULL);
if (this->header.len > 0) {
RichString_delete(this->header);
}
this->header = header; this->header = header;
this->needsRedraw = true; this->needsRedraw = true;
} }
@ -274,7 +270,8 @@ void Panel_draw(Panel* this, bool focus) {
for(int i = first, j = 0; j < this->h && i < last; i++, j++) { for(int i = first, j = 0; j < this->h && i < last; i++, j++) {
Object* itemObj = Vector_get(this->items, i); Object* itemObj = Vector_get(this->items, i);
RichString itemRef = RichString_new(); RichString itemRef;
RichString_initVal(itemRef);
itemObj->display(itemObj, &itemRef); itemObj->display(itemObj, &itemRef);
int amt = MIN(itemRef.len - scrollH, this->w); int amt = MIN(itemRef.len - scrollH, this->w);
if (i == this->selected) { if (i == this->selected) {
@ -296,10 +293,12 @@ void Panel_draw(Panel* this, bool focus) {
} else { } else {
Object* oldObj = Vector_get(this->items, this->oldSelected); Object* oldObj = Vector_get(this->items, this->oldSelected);
RichString oldRef = RichString_new(); RichString oldRef;
RichString_initVal(oldRef);
oldObj->display(oldObj, &oldRef); oldObj->display(oldObj, &oldRef);
Object* newObj = Vector_get(this->items, this->selected); Object* newObj = Vector_get(this->items, this->selected);
RichString newRef = RichString_new(); RichString newRef;
RichString_initVal(newRef);
newObj->display(newObj, &newRef); newObj->display(newObj, &newRef);
mvhline(y+ this->oldSelected - this->scrollV, x+0, ' ', this->w); mvhline(y+ this->oldSelected - this->scrollV, x+0, ' ', this->w);
if (scrollH < oldRef.len) if (scrollH < oldRef.len)

View File

@ -150,7 +150,7 @@ void Process_delete(Object* cast) {
void Process_display(Object* cast, RichString* out) { void Process_display(Object* cast, RichString* out) {
Process* this = (Process*) cast; Process* this = (Process*) cast;
ProcessField* fields = this->pl->fields; ProcessField* fields = this->pl->fields;
RichString_prune(out); RichString_init(out);
for (int i = 0; fields[i]; i++) for (int i = 0; fields[i]; i++)
Process_writeField(this, out, fields[i]); Process_writeField(this, out, fields[i]);
if (this->pl->shadowOtherUsers && this->st_uid != getuid()) if (this->pl->shadowOtherUsers && this->st_uid != getuid())

View File

@ -177,7 +177,7 @@ ProcessList* ProcessList_new(UsersTable* usersTable) {
ProcessList* this; ProcessList* this;
this = malloc(sizeof(ProcessList)); this = malloc(sizeof(ProcessList));
this->processes = Vector_new(PROCESS_CLASS, true, DEFAULT_SIZE, Process_compare); this->processes = Vector_new(PROCESS_CLASS, true, DEFAULT_SIZE, Process_compare);
this->processTable = Hashtable_new(20, false); this->processTable = Hashtable_new(70, false);
this->prototype = Process_new(this); this->prototype = Process_new(this);
this->usersTable = usersTable; this->usersTable = usersTable;
@ -265,7 +265,8 @@ void ProcessList_invertSortOrder(ProcessList* this) {
} }
RichString ProcessList_printHeader(ProcessList* this) { RichString ProcessList_printHeader(ProcessList* this) {
RichString out = RichString_new(); RichString out;
RichString_init(&out);
ProcessField* fields = this->fields; ProcessField* fields = this->fields;
for (int i = 0; fields[i]; i++) { for (int i = 0; fields[i]; i++) {
char* field = Process_printField(fields[i]); char* field = Process_printField(fields[i]);
@ -505,31 +506,9 @@ void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, fl
process->pid = pid; process->pid = pid;
if (! ProcessList_readStatusFile(this, process, dirname, name)) if (! ProcessList_readStatusFile(this, process, dirname, name))
goto errorReadingProcess; goto errorReadingProcess;
char* username = UsersTable_getRef(this->usersTable, process->st_uid);
if (username) {
strncpy(process->user, username, PROCESS_USER_LEN);
} else {
snprintf(process->user, PROCESS_USER_LEN, "%d", process->st_uid);
}
} }
process->updated = true; process->updated = true;
int lasttimes = (process->utime + process->stime);
snprintf(statusfilename, MAX_NAME, "%s/%s/stat", dirname, name);
status = ProcessList_fopen(this, statusfilename, "r");
if (status == NULL)
goto errorReadingProcess;
int success = ProcessList_readStatFile(this, process, status, command);
fclose(status);
if(!success)
goto errorReadingProcess;
process->percent_cpu = (process->utime + process->stime - lasttimes) /
period * 100.0;
snprintf(statusfilename, MAX_NAME, "%s/%s/statm", dirname, name); snprintf(statusfilename, MAX_NAME, "%s/%s/statm", dirname, name);
status = ProcessList_fopen(this, statusfilename, "r"); status = ProcessList_fopen(this, statusfilename, "r");
@ -548,7 +527,27 @@ void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, fl
if (this->hideKernelThreads && process->m_size == 0) if (this->hideKernelThreads && process->m_size == 0)
goto errorReadingProcess; goto errorReadingProcess;
int lasttimes = (process->utime + process->stime);
snprintf(statusfilename, MAX_NAME, "%s/%s/stat", dirname, name);
status = ProcessList_fopen(this, statusfilename, "r");
if (status == NULL)
goto errorReadingProcess;
int success = ProcessList_readStatFile(this, process, status, command);
fclose(status);
if(!success)
goto errorReadingProcess;
if(!existingProcess) { if(!existingProcess) {
char* username = UsersTable_getRef(this->usersTable, process->st_uid);
if (username) {
strncpy(process->user, username, PROCESS_USER_LEN);
} else {
snprintf(process->user, PROCESS_USER_LEN, "%d", process->st_uid);
}
snprintf(statusfilename, MAX_NAME, "%s/%s/cmdline", dirname, name); snprintf(statusfilename, MAX_NAME, "%s/%s/cmdline", dirname, name);
status = ProcessList_fopen(this, statusfilename, "r"); status = ProcessList_fopen(this, statusfilename, "r");
if (!status) { if (!status) {
@ -567,6 +566,9 @@ void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, fl
fclose(status); fclose(status);
} }
process->percent_cpu = (process->utime + process->stime - lasttimes) /
period * 100.0;
process->percent_mem = process->m_resident / process->percent_mem = process->m_resident /
(float)(this->usedMem - this->cachedMem - this->buffersMem) * (float)(this->usedMem - this->cachedMem - this->buffersMem) *
100.0; 100.0;

View File

@ -12,6 +12,9 @@
/*{ /*{
#define RichString_init(this) (this)->len = 0
#define RichString_initVal(this) (this).len = 0
typedef struct RichString_ { typedef struct RichString_ {
int len; int len;
chtype chstr[RICHSTRING_MAXLEN+1]; chtype chstr[RICHSTRING_MAXLEN+1];
@ -23,23 +26,8 @@ typedef struct RichString_ {
#define MIN(a,b) ((a)<(b)?(a):(b)) #define MIN(a,b) ((a)<(b)?(a):(b))
#endif #endif
static WINDOW* workArea = NULL;
RichString RichString_new() {
RichString this;
this.len = 0;
return this;
}
void RichString_delete(RichString this) {
}
void RichString_prune(RichString* this) {
this->len = 0;
}
void RichString_write(RichString* this, int attrs, char* data) { void RichString_write(RichString* this, int attrs, char* data) {
this->len = 0; RichString_init(this);
RichString_append(this, attrs, data); RichString_append(this, attrs, data);
} }
@ -48,35 +36,32 @@ inline void RichString_append(RichString* this, int attrs, char* data) {
} }
inline void RichString_appendn(RichString* this, int attrs, char* data, int len) { inline void RichString_appendn(RichString* this, int attrs, char* data, int len) {
if (!workArea) { int last = MIN(RICHSTRING_MAXLEN - 1, len + this->len);
workArea = newpad(1, RICHSTRING_MAXLEN); for (int i = this->len, j = 0; i < last; i++, j++)
} this->chstr[i] = data[j] | attrs;
assert(workArea); this->chstr[last] = 0;
wattrset(workArea, attrs); this->len = last;
int maxToWrite = (RICHSTRING_MAXLEN - 1) - this->len;
int wrote = MIN(maxToWrite, len);
mvwaddnstr(workArea, 0, 0, data, maxToWrite);
int oldstrlen = this->len;
this->len += wrote;
mvwinchnstr(workArea, 0, 0, this->chstr + oldstrlen, wrote);
wattroff(workArea, attrs);
} }
void RichString_setAttr(RichString *this, int attrs) { void RichString_setAttr(RichString *this, int attrs) {
chtype* ch = this->chstr;
for (int i = 0; i < this->len; i++) { for (int i = 0; i < this->len; i++) {
char c = this->chstr[i]; *ch = (*ch & 0xff) | attrs;
this->chstr[i] = c | attrs; ch++;
} }
} }
void RichString_applyAttr(RichString *this, int attrs) { void RichString_applyAttr(RichString *this, int attrs) {
for (int i = 0; i < this->len - 1; i++) { chtype* ch = this->chstr;
this->chstr[i] |= attrs; for (int i = 0; i < this->len; i++) {
*ch |= attrs;
ch++;
} }
} }
RichString RichString_quickString(int attrs, char* data) { RichString RichString_quickString(int attrs, char* data) {
RichString str = RichString_new(); RichString str;
RichString_initVal(str);
RichString_write(&str, attrs, data); RichString_write(&str, attrs, data);
return str; return str;
} }

View File

@ -14,6 +14,9 @@
#define RICHSTRING_MAXLEN 300 #define RICHSTRING_MAXLEN 300
#define RichString_init(this) (this)->len = 0
#define RichString_initVal(this) (this).len = 0
typedef struct RichString_ { typedef struct RichString_ {
int len; int len;
chtype chstr[RICHSTRING_MAXLEN+1]; chtype chstr[RICHSTRING_MAXLEN+1];
@ -24,12 +27,6 @@ typedef struct RichString_ {
#define MIN(a,b) ((a)<(b)?(a):(b)) #define MIN(a,b) ((a)<(b)?(a):(b))
#endif #endif
RichString RichString_new();
void RichString_delete(RichString this);
void RichString_prune(RichString* this);
void RichString_write(RichString* this, int attrs, char* data); void RichString_write(RichString* this, int attrs, char* data);
inline void RichString_append(RichString* this, int attrs, char* data); inline void RichString_append(RichString* this, int attrs, char* data);

View File

@ -46,7 +46,7 @@ void SwapMeter_display(Object* cast, RichString* out) {
char buffer[50]; char buffer[50];
Meter* this = (Meter*)cast; Meter* this = (Meter*)cast;
long int swap = (long int) this->values[0]; long int swap = (long int) this->values[0];
RichString_prune(out); RichString_init(out);
RichString_append(out, CRT_colors[METER_TEXT], ":"); RichString_append(out, CRT_colors[METER_TEXT], ":");
sprintf(buffer, "%ldM ", (long int) this->total / 1024); sprintf(buffer, "%ldM ", (long int) this->total / 1024);
RichString_append(out, CRT_colors[METER_VALUE], buffer); RichString_append(out, CRT_colors[METER_VALUE], buffer);

View File

@ -38,7 +38,7 @@ void TasksMeter_setValues(Meter* this, char* buffer, int len) {
void TasksMeter_display(Object* cast, RichString* out) { void TasksMeter_display(Object* cast, RichString* out) {
Meter* this = (Meter*)cast; Meter* this = (Meter*)cast;
RichString_prune(out); RichString_init(out);
char buffer[20]; char buffer[20];
sprintf(buffer, "%d", (int)this->total); sprintf(buffer, "%d", (int)this->total);
RichString_append(out, CRT_colors[METER_VALUE], buffer); RichString_append(out, CRT_colors[METER_VALUE], buffer);