SP 과제...
먼저 입력값을 그룹별로 나눠야 할 필요성이 있기에.. 크게 3가지 그룹으로 분리..
1. 랜덤한 인풋그럼 성능 비교 시작..
이런 이런.. 별반 차이가 없군..
그냥 최대 허용 노드수만 늘리면 장땡..
2. 순차적 인풋성능은 뭐가 더 좋을까나!?..
그렇군열~ MRU 승..
간단히 머리 굴려보면..
계속해서 다른 수가 들어오는 것이 아니라, 어느 정도 들어온 다음에 다시 이전의 값에서부터 시작하고, MRU로 자료를 유지했다면 앞부분의 자료만 변했기에, 다시 예전의 값에서 시작할 때 Update가 호출되기땜시 승.. LRU면.. 예전께 남아 있을리 만무..
3. 말로 표현하기 힘든 인풋.. (펄스는 아니고.. 뭐라고 하지 ㅡ_ㅡ??..)성능비교 시작..
이번엔 LRU 승..
빈번하게 들어오는 입력값이 많으니..
기존 리스트에 있는 Data에 대한 Update 함수의 호출이 많아질 것이고..
Update 함수를 자주 사용한다면, 빈번히 호출되는 자료를 리스트의 앞쪽에 보관하게 될꺼고..
상대적으로 적게 사용되는 것들을 끝으로 밀어서 새로운 자료가 들어왔을 때..
안쓰는 것들을 지워야 효율적일테고..
위의 말 종합하면..LRU 쓰삼이란 뜻이고..
그래서 LRU의 승리고..
뭐.. 그렇고 그런 이야기 ㅡ_ㅡ..
그럼.. 코드 구현은 어떻게!??..
#include
#include
#include
#include
#ifndef TABLESIZE
#define TABLESIZE 10
#endif
#define HASH(a) ((a) % TABLESIZE)
typedef struct Node {
int data;
struct Node *right;
struct Node *next;
} Node;
Node *head, HashTable[TABLESIZE];
int MaxItem, ItemCounter;
int _Insert(int data);
int Insert(int data, char* policy);
Node* Search(int data, Node** end);
void Update(Node* node);
void func_select(char* policy, Node* p);
void UnlinkMRU(Node* temp);
void UnlinkLRU(Node* temp);
void Delete(Node* node);
char* print(Node* p)
{
static char buf[1024], t[16];
for ( memset(buf,'\0',sizeof(char) * 1024);
p != NULL;
sprintf(t, "%d ", p->data), strcat(buf, t), p=p->right ) ;
return buf;
}
void printTable()
{
int i;
Node* p;
for (i=0; inext)
printf("%d ", p->data);
putchar('\n');
}
}
int main(int argc, char* argv[])
{
int data, ret;
char mode[4];
FILE* fp;
if (argc != 3) exit(1);
if ((MaxItem = atoi(argv[1])) == 0) exit(1);
if ((fp = fopen(argv[2],"r")) == NULL) exit(1);
memset((head=(Node*) malloc(sizeof(Node))), 0x00, sizeof(Node));
while (!feof(fp) && fscanf(fp, "%3s %d", mode, &data))
{
#ifdef DEBUG
printf("input : %3s, %d\n", mode, data);
printf("before entity list : %s\n", !ItemCounter ? "empty" : print(head->right));
#endif
ret = Insert(data, mode);
#ifdef DEBUG
printf("%d is %s in the list.\n", data, ret ? "missing" : "found");
printf("after entity list : %s\n", print(head->right));
printTable();
putchar('\n');
#endif
}
printf("final entity list : %s\n", print(head->right));
printTable();
return 0;
}
// 실제 데이터를 리스트에 추가
int _Insert(int data)
{
Node* temp;
memset((temp = (Node*) malloc(sizeof(Node))), 0x00, sizeof(Node));
temp->data = data; // 해시 테이블 연결부
temp->next = HashTable[HASH(data)].next;
HashTable[HASH(data)].next = temp;
temp->right = head->right; // 우선순위 리스트 연결부
head->right = temp;
return ++ItemCounter;
}
// 선택적 삽입을 위한 분기점
int Insert(int data, char* policy)
{
Node *temp, *end;
if ((temp = Search(data, &end)) == NULL && ItemCounter < MaxItem)
return _Insert(data); // 없는 자료 & 공간 존재
else if (temp == NULL && ItemCounter >= MaxItem)
{
func_select(policy, end);
return _Insert(data); // 없는 자료 & 공간 무
}
else // 이미 있는 자료일때
return Update(temp), 0;
}
// 자료를 찾아서 존재한다면 바로 전 노드를 반환 (해시 테이블)
Node* Search(int data, Node** p)
{ // p 포인터는 RefCount를 줄여보기 위한 발악
for (*p=HashTable+HASH(data); (*p)->next != NULL; *p=(*p)->next)
if ((*p)->next->data == data)
return (*p)->next;
return NULL;
}
// 넘어온 노드의 우선순위리스트 전까지 이동해서 수정 (우선순위 리스트)
void Update(Node* node)
{
Node *p, *target;
if (head->right == node)
return ;
for (p=head; p->right != node; p=p->right) ;
target = p->right;
p->right = p->right->right;
target->right = head->right;
head->right = target;
}
// Delete 방법 호출 판단 및 레퍼런스 카운트 줄이기 대작전
void func_select(char* policy, Node* p) // 우선순위 리스트의 값
{
static void (*fp[2])(Node*) = { &UnlinkLRU, &UnlinkMRU };
int mode = !strcmp(policy, "MRU");
if (!mode && p->right == NULL)
p = (p->right != NULL && p->right->next != NULL) ? p->right : head;
(fp[mode])(p);
}
// 앞의 노드를 삭제 -- 해시 테이블도 조절해야함 (우선순위 리스트)
void UnlinkMRU(Node* temp)
{ //여기 temp는 안씀
temp = head->right;
head->right = head->right->right;
Delete(temp);
}
// 넘어오는 p의 위치에서 부터 찾도록 수정 (우선순위 리스트)
void UnlinkLRU(Node* p)
{ // 그나마 처음부터 검색하지 않게 하기 위함
for (; p->right!=NULL; p=p->right)
if (p->right->right == NULL)
break;
Delete(p->right);
p->right = NULL; // 윗쪽에 1번 더 카운팅 되기에 여기선 안함
}
// 넘어오는노드 전까지 이동해서 삭제 (해시테이블)
void Delete(Node* node)
{
Node *p;
for (p=HashTable+HASH(node->data); p->next != node; p=p->next) ;
p->next = p->next->next;
free(node);
}
더블 리스트 쓰지 말라니.. 닥치고 쓰지 말아야지 ㅡ_ㅡ..
말을 참 잘 듣는 착한 학생..
http://d-story.net/tc/lab/trackback/257