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) {
char buffer[50];
Meter* this = (Meter*)cast;
RichString_prune(out);
RichString_init(out);
sprintf(buffer, "%5.1f%% ", this->values[1]);
RichString_append(out, CRT_colors[METER_TEXT], ":");
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 void(*Hashtable_PairFunction)(int, void*, void*);
typedef int(*Hashtable_HashAlgorithm)(Hashtable*, int);
typedef struct HashtableItem {
int key;
@ -28,7 +27,6 @@ struct Hashtable_ {
int size;
HashtableItem** buckets;
int items;
Hashtable_HashAlgorithm hashAlgorithm;
bool owner;
};
}*/
@ -49,15 +47,10 @@ Hashtable* Hashtable_new(int size, bool owner) {
this = (Hashtable*) malloc(sizeof(Hashtable));
this->size = size;
this->buckets = (HashtableItem**) calloc(sizeof(HashtableItem*), size);
this->hashAlgorithm = Hashtable_hashAlgorithm;
this->owner = owner;
return this;
}
int Hashtable_hashAlgorithm(Hashtable* this, int key) {
return key % this->size;
}
void Hashtable_delete(Hashtable* this) {
for (int i = 0; i < this->size; 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) {
int index = this->hashAlgorithm(this, key);
int index = key % this->size;
HashtableItem** bucketPtr = &(this->buckets[index]);
while (true)
if (*bucketPtr == NULL) {
@ -95,7 +88,7 @@ void Hashtable_put(Hashtable* this, int key, void* value) {
}
void* Hashtable_remove(Hashtable* this, int key) {
int index = this->hashAlgorithm(this, key);
int index = key % this->size;
HashtableItem** bucketPtr = &(this->buckets[index]);
while (true)
if (*bucketPtr == NULL) {
@ -118,7 +111,7 @@ void* Hashtable_remove(Hashtable* this, int key) {
}
//#include <stdio.h>
inline void* Hashtable_get(Hashtable* this, int key) {
int index = this->hashAlgorithm(this, key);
int index = key % this->size;
HashtableItem* bucketPtr = this->buckets[index];
// fprintf(stderr, "%d -> %d\n", key, index);
while (true) {

View File

@ -18,7 +18,6 @@ in the source distribution for its full text.
typedef struct Hashtable_ Hashtable;
typedef void(*Hashtable_PairFunction)(int, void*, void*);
typedef int(*Hashtable_HashAlgorithm)(Hashtable*, int);
typedef struct HashtableItem {
int key;
@ -30,7 +29,6 @@ struct Hashtable_ {
int size;
HashtableItem** buckets;
int items;
Hashtable_HashAlgorithm hashAlgorithm;
bool owner;
};
@ -38,8 +36,6 @@ HashtableItem* HashtableItem_new(int key, void* value);
Hashtable* Hashtable_new(int size, bool owner);
int Hashtable_hashAlgorithm(Hashtable* this, int key);
void Hashtable_delete(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) {
Meter* this = (Meter*)cast;
char buffer[20];
RichString_prune(out);
RichString_init(out);
sprintf(buffer, "%.2f ", this->values[2]);
RichString_append(out, CRT_colors[LOAD_AVERAGE_FIFTEEN], buffer);
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) {
Meter* this = (Meter*)cast;
char buffer[20];
RichString_prune(out);
RichString_init(out);
sprintf(buffer, "%.2f ", ((Meter*)this)->values[0]);
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 buffersMem = this->values[1] / div;
long int cachedMem = this->values[2] / div;
RichString_prune(out);
RichString_init(out);
RichString_append(out, CRT_colors[METER_TEXT], ":");
sprintf(buffer, format, totalMem);
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) {
display((Object*)this, &Meter_stringBuffer);
} else {
RichString_prune(&Meter_stringBuffer);
RichString_initVal(Meter_stringBuffer);
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) {
assert (this != NULL);
RichString_delete(this->header);
Vector_delete(this->items);
}
inline void Panel_setRichHeader(Panel* this, RichString header) {
assert (this != NULL);
if (this->header.len > 0) {
RichString_delete(this->header);
}
this->header = header;
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++) {
Object* itemObj = Vector_get(this->items, i);
RichString itemRef = RichString_new();
RichString itemRef;
RichString_initVal(itemRef);
itemObj->display(itemObj, &itemRef);
int amt = MIN(itemRef.len - scrollH, this->w);
if (i == this->selected) {
@ -296,10 +293,12 @@ void Panel_draw(Panel* this, bool focus) {
} else {
Object* oldObj = Vector_get(this->items, this->oldSelected);
RichString oldRef = RichString_new();
RichString oldRef;
RichString_initVal(oldRef);
oldObj->display(oldObj, &oldRef);
Object* newObj = Vector_get(this->items, this->selected);
RichString newRef = RichString_new();
RichString newRef;
RichString_initVal(newRef);
newObj->display(newObj, &newRef);
mvhline(y+ this->oldSelected - this->scrollV, x+0, ' ', this->w);
if (scrollH < oldRef.len)

View File

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

View File

@ -177,7 +177,7 @@ ProcessList* ProcessList_new(UsersTable* usersTable) {
ProcessList* this;
this = malloc(sizeof(ProcessList));
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->usersTable = usersTable;
@ -265,7 +265,8 @@ void ProcessList_invertSortOrder(ProcessList* this) {
}
RichString ProcessList_printHeader(ProcessList* this) {
RichString out = RichString_new();
RichString out;
RichString_init(&out);
ProcessField* fields = this->fields;
for (int i = 0; fields[i]; i++) {
char* field = Process_printField(fields[i]);
@ -505,31 +506,9 @@ void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, fl
process->pid = pid;
if (! ProcessList_readStatusFile(this, process, dirname, name))
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;
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);
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)
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) {
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);
status = ProcessList_fopen(this, statusfilename, "r");
if (!status) {
@ -567,6 +566,9 @@ void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, fl
fclose(status);
}
process->percent_cpu = (process->utime + process->stime - lasttimes) /
period * 100.0;
process->percent_mem = process->m_resident /
(float)(this->usedMem - this->cachedMem - this->buffersMem) *
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_ {
int len;
chtype chstr[RICHSTRING_MAXLEN+1];
@ -23,23 +26,8 @@ typedef struct RichString_ {
#define MIN(a,b) ((a)<(b)?(a):(b))
#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) {
this->len = 0;
RichString_init(this);
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) {
if (!workArea) {
workArea = newpad(1, RICHSTRING_MAXLEN);
}
assert(workArea);
wattrset(workArea, attrs);
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);
int last = MIN(RICHSTRING_MAXLEN - 1, len + this->len);
for (int i = this->len, j = 0; i < last; i++, j++)
this->chstr[i] = data[j] | attrs;
this->chstr[last] = 0;
this->len = last;
}
void RichString_setAttr(RichString *this, int attrs) {
chtype* ch = this->chstr;
for (int i = 0; i < this->len; i++) {
char c = this->chstr[i];
this->chstr[i] = c | attrs;
*ch = (*ch & 0xff) | attrs;
ch++;
}
}
void RichString_applyAttr(RichString *this, int attrs) {
for (int i = 0; i < this->len - 1; i++) {
this->chstr[i] |= attrs;
chtype* ch = this->chstr;
for (int i = 0; i < this->len; i++) {
*ch |= attrs;
ch++;
}
}
RichString RichString_quickString(int attrs, char* data) {
RichString str = RichString_new();
RichString str;
RichString_initVal(str);
RichString_write(&str, attrs, data);
return str;
}

View File

@ -14,6 +14,9 @@
#define RICHSTRING_MAXLEN 300
#define RichString_init(this) (this)->len = 0
#define RichString_initVal(this) (this).len = 0
typedef struct RichString_ {
int len;
chtype chstr[RICHSTRING_MAXLEN+1];
@ -24,12 +27,6 @@ typedef struct RichString_ {
#define MIN(a,b) ((a)<(b)?(a):(b))
#endif
RichString RichString_new();
void RichString_delete(RichString this);
void RichString_prune(RichString* this);
void RichString_write(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];
Meter* this = (Meter*)cast;
long int swap = (long int) this->values[0];
RichString_prune(out);
RichString_init(out);
RichString_append(out, CRT_colors[METER_TEXT], ":");
sprintf(buffer, "%ldM ", (long int) this->total / 1024);
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) {
Meter* this = (Meter*)cast;
RichString_prune(out);
RichString_init(out);
char buffer[20];
sprintf(buffer, "%d", (int)this->total);
RichString_append(out, CRT_colors[METER_VALUE], buffer);