설치 및 제거
본 장에서는 ProSort의 설치 및 실행 확인, 제거 방법을 설명한다.
1. 설치
1.1. 압축 파일 실행
ProSort를 설치하는 순서는 다음과 같다.
-
설치를 원하는 디렉터리에서 바이너리 압축 파일(.gz)을 해제하면 다음과 같은 디렉터리 구조가 나타난다.
prosort |----- bin | |----- prosort | |----- psapi | |----- psctl | |----- pserr |----- config | |----- gen_tip.sh | |----- prosort_tip.template | |----- revision | |----- variant |----- docs |----- include | |----- prosort.h | |----- prosort_rc.h |----- lib | |----- libprosort.a | |----- libprosort.so +----- license +----- tests
ProSort에서 사용하는 디렉터리는 다음과 같다.
- bin
-
ProSort의 실행 파일과 각종 유틸리티가 있는 디렉터리이다. 이 디렉터리에는 다음과 같은 유틸리티가 있다.
유틸리티 설명 prosort
데이터의 정렬, 병합, 변환 등을 수행한다.
psapi
ProSort API로 데이터의 정렬, 병합, 변환 등을 수행한다.
psctl
특정한 조건을 만족하는 데이터 파일을 생성한다.
pserr
에러 코드에 대한 상세 설명을 보여 준다.
- config
-
ProSort를 실행하기 위한 설정 파일이 있는 디렉터리이다.
- docs
-
ProSort 안내서가 있는 디렉터리이다.
- include
-
ProSort API를 이용하여 애플리케이션 프로그램을 작성할 때 필요한 헤더 파일이 있는 디렉터리이다.
- lib
-
ProSort API를 이용하여 애플리케이션 프로그램을 작성할 때 필요한 라이브러리 파일이 있는 디렉터리이다.
- license
-
ProSort의 라이선스 파일(license.xml)이 있는 디렉터리이다. XML 형식이므로, 일반 텍스트 편집기로도 라이선스의 내용을 확인할 수 있다.
- tests
-
ProSort Script의 예제 파일과 프로그램이 있는 디렉터리이다.
-
prosort/bin 디렉터리에서 prosort를 실행한다.
prosort를 실행하면 별도의 설치 과정 없이 바로 ProSort가 실행된다.
1.2. 파라미터 설정
ProSort의 실행을 위해서는 $PROSORT_SID.tip 파일에 파라미터를 설정해야 한다. 각 파라미터는 ProSort의 메모리 크기 및 프로세스의 조정을 위해 사용된다.
기본적으로 제공되는 파라미터는 config 디렉터리에 있는 gen_tip.sh 스크립트 파일을 실행하면 자동으로 생성된다.
다음은 파라미터의 설정 예이다.
<$PROSORT_SID.tip>
SORT_THREAD_COUNT=2 SORT_READ_BLK_SIZE=4194304 SORT_WRITE_BLK_SIZE=65536 MERGE_READ_BLK_SIZE=2097152 USE_AIO_READ=Y USE_AIO_WRITE=Y MAXIMIZE_MEM_RUN_SIZE=Y USE_STRICT_MEMORY=Y
|
자세한 내용은 파라미터를 참고한다. |
2. 실행 확인
본 절에서는 prosort 명령어와 API로 제공되는 함수를 사용하여 설치된 ProSort가 정상적으로 실행되는지를 확인한다.
2.1. ProSort 명령어
prosort 명령어는 ProSort가 설치된 머신에서 실행해야 한다. 또한, 명령어를 실행하기 전에 반드시 환경 변수가 제대로 설정되어 있어야 한다.
prosort 명령어의 사용법은 다음과 같다.
prosort [-h] [-v] [-s] [-j] [script file]
| 옵션 | 설명 |
|---|---|
-h |
|
-v |
ProSort의 버전 정보를 보여주는 옵션이다. |
-s |
스크립트 파일을 실행한 후 상태 정보를 보여주는 옵션이다. -s 옵션을 사용하면 다음의 상태 정보를 확인할 수 있다.
|
-j |
스크립트 파일을 실행한 후 프로파일의 정보를 보여주는 옵션이다. 프로파일의 정보는 제품의 버전에 따라 변경될 수 있으므로, 본 안내서에서는 별도로 설명하지 않는다. |
script file |
스크립트 파일의 디렉터리 경로와 이름을 입력한다. 생략하면 표준 입력을 통해 스크립트 파일을 입력받는다. |
2.2. ProSort API 함수
ProSort는 C 함수의 형태로 API를 제공한다. 모든 함수는 반환값을 가지며, 성공할 경우에는 0을 반환하고 실패할 경우에는 음수 값을 반환한다.
API로 제공되는 함수는 다음과 같다.
| 함수 | 설명 |
|---|---|
스크립트(script)의 연산을 모두 수행하는 함수이다. |
|
ProSort 실행에 필요한 정보를 초기화한다. |
|
모든 입출력 파라미터가 prosort_setup 함수와 동일하다. |
|
SORT 연산을 할 때 데이터를 레코드별로 입력하는 함수이다. |
|
SORT 연산을 할 때 데이터 입력이 끝났음을 나타내는 함수이다. |
|
연산의 결과를 레코드 건별로 가져오는 함수이다. |
|
모든 연산에 사용한 리소스를 반환하는 함수이다. |
|
에러가 발생했을 때 에러 번호를 가져오는 함수이다. |
|
에러가 발생했을 때 에러 메시지를 가져오는 함수이다. |
2.2.1. prosort_run_script
스크립트(script)의 연산을 모두 수행하는 함수이다.
-
프로토타입
int prosort_run_script(const char *const script);
-
파라미터
파라미터 설명 script
연산에 사용할 ProSort의 스크립트(script)이다.
-
예제
#include <stdio.h> #include <stdlib.h> #include "prosort.h" int main(int argc, char **argv) { int rc; char *script = "DEFREC FIXED,SIZE=256 " "MEMORY 500M " "INFILE = (x1,100M, x2, 100M, x3, 100M, x4, 100M) " "SORT FIELDS=(1,13,AC,A) " "OUTFIL FNAMES = xresult "; rc = prosort_run_script (script); if (rc < 0) { fprintf(stderr,"Error[%d]:\n", rc); fprintf(stderr,"%s\n", ps_err_code_to_cause(rc)); fprintf(stderr,"%s\n", ps_err_code_to_action(rc)); exit (rc); } return 0; }
2.2.2. prosort_setup
ProSort 실행에 필요한 정보를 초기화한다. 단, prosort_run_script 함수를 사용할 경우에는 prosort_setup 함수를 호출할 필요가 없다.
-
프로토타입
typedef int (*callback_func_t)(char **data_buf_addr, int *data_buf_length); int prosort_setup (const char *prosort_script, callback_func_t *data_fetch_callback_funcs, int data_fetch_callback_func_cnt, void **ptr_prosort_context); -
파라미터
파라미터 설명 *prosort_script
ProSort API에서 사용할 스크립트이다.
*data_fetch_callback_funcs
MERGE 및 COPY 연산을 할 때에는 데이터를 별도로 입력받지 않고, callback function를 통해 입력 받는다.
특히, MERGE 연산을 할 때에는 여러 callback function를 입력받을 수 있으므로, callback function의 배열 주소를 파라미터로 받는다.
data_fetch_callback_func_cnt
callback function의 개수이다.
**ptr_prosort_context
연산 수행을 위해 필요한 컨텍스트(context)의 정보를 얻는다. 생성된 컨텍스트는 다른 API에 적용하여 연산을 수행할 수 있다.
-
예제
#include <stdio.h> #include <stdlib.h> #include "prosort.h" static void print_err_msg(int ec) { fprintf(stderr,"Error[%d]:\n", ec); fprintf(stderr,"%s\n", ps_err_code_to_cause(ec)); fprintf(stderr,"%s\n", ps_err_code_to_action(ec)); fprintf(stderr,"%s\n", ps_err_get_last_msg()); } /* 16byte 레코드 */ #define REC_LEN 16 #define RAND (char) (rand() % 24) + 'A' int main(int argc, char **argv) { int i = 0; int j = 0; int rc = 0; void *ps_ctx; char buf[REC_LEN]; const char *script = "MEMORY 100M\n" "DATASIZE 100M\n" "DEFREC FIXED, SIZE=16\n" "SORT FIELDS = (1,8,CH,A)\n"; /* 스크립트 설정 */ rc = prosort_setup (script, NULL, 0, &ps_ctx); if (rc < 0) { print_err_msg (rc); exit (rc); } /* 레코드 입력 */ for (i = 0; i < 100; i++) { for (j = 0; j < REC_LEN - 1; j++) buf[j] = RAND; buf[j] = 0; rc = prosort_release_record (ps_ctx, buf, REC_LEN); if (rc < 0) { print_err_msg (rc); exit (rc); } } /* 레코드 입력 완료 */ prosort_release_end (ps_ctx); do { char outbuf[REC_LEN]; char *outbufs[1]; unsigned int len = REC_LEN; outbufs[0] = outbuf; rc = prosort_return_record (ps_ctx, outbufs, &len); if (rc < 0) { print_err_msg (rc); exit (rc); } if (len == 0) break; printf ("%s\n", outbuf); } while (1); prosort_end (ps_ctx); return 0; }
2.2.3. prosort_setup_with_userexit
모든 입출력 파라미터가 prosort_setup 함수와 동일하다. 단, func_e15, func_e32, func_e35, func_e61 파라미터는 제외이다.
-
프로토타입
typedef int (*user_exit_func_t)(const void *rec_addr, const int rec_len, int file_no, void **ret_rec_addr, int *ret_rec_len); int prosort_setup_with_userexit(const char *prosort_script, callback_func_t *data_fetch_callback_funcs, int data_fetch_callback_func_cnt, user_exit_func_t func_e15, user_exit_func_t func_e32, user_exit_func_t func_e35, user_exit_func_t func_e61, void **ptr_prosort_context); -
파라미터
파라미터 설명 *prosort_script
ProSort API에서 사용할 스크립트이다.
*data_fetch_callback_funcs
MERGE 및 COPY 연산을 할 때에는 데이터를 별도로 입력받지 않고, callback function를 통해 입력 받는다.
특히, MERGE 연산을 할 때에는 여러 callback function를 입력받을 수 있으므로, callback function의 배열 주소를 파라미터로 받는다.
data_fetch_callback_func_cnt
callback function의 개수이다.
func_e15
User Exit Function E15 이다.
func_e32
User Exit Function E32 이다.
func_e35
User Exit Function E35 이다.
func_e61
User Exit Function E61 이다.
**ptr_prosort_context
연산 수행을 위해 필요한 컨텍스트의 정보를 얻는다. 생성된 컨텍스트는 다른 API에 적용하여 연산을 수행할 수 있다.
-
예제
int func_e15(const void *rec_addr, const int rec_len, int file_no, void **ret_rec_addr, int *ret_rec_len) { ... } int main(int argc, char **argv) { int rc; void *ps_ctx; const char *script = "DEFREC FIXED,SIZE=150 \n" "DATASIZE 2M \n" "MEMORY 512M \n" "WORKSPACE = (./) \n" "SORT FIELDS=(1,2,A),FORMAT=BI \n" "INCLUDE COND=(1,2,CH,EQ,C'12',OR,1,2,CH,EQ,C'22',OR,1,2,CH,EQ,C'32') \n" "OUTFIL FNAMES=OUT1 \n"; rc = prosort_setup_with_userexit(script, NULL, 0, func_e15, NULL, NULL, NULL, &ps_ctx); ... }
2.2.4. prosort_release_record
SORT 연산을 할 때 데이터를 레코드별로 입력하는 함수이다.
-
프로토타입
int prosort_release_record(void *prosort_context, const char *record, const unsigned int record_length); -
파라미터
파라미터 설명 *prosort_context
prosort_setup 함수에서 생성한 컨텍스트를 전달한다.
*record
레코드가 있는 주소이다.
record_length
레코드의 길이이다.
-
예제
#include <stdio.h> #include <stdlib.h> #include "prosort.h" static void print_err_msg(int ec) { fprintf(stderr,"Error[%d]:\n", ec); fprintf(stderr,"%s\n", ps_err_code_to_cause(ec)); fprintf(stderr,"%s\n", ps_err_code_to_action(ec)); fprintf(stderr,"%s\n", ps_err_get_last_msg()); } /* 16byte 레코드 */ #define REC_LEN 16 #define RAND (char) (rand() % 24) + 'A' int main(int argc, char **argv) { int i = 0; int j = 0; int rc = 0; void *ps_ctx; char buf[REC_LEN]; const char *script = "MEMORY 100M\n" "DATASIZE 100M\n" "DEFREC FIXED, SIZE=16\n" "SORT FIELDS = (1,8,CH,A)\n"; /* 스크립트 설정 */ rc = prosort_setup (script, NULL, 0, &ps_ctx); if (rc < 0) { print_err_msg (rc); exit (rc); } /* 레코드 입력 */ for (i = 0; i < 100; i++) { for (j = 0; j < REC_LEN - 1; j++) buf[j] = RAND; buf[j] = 0; rc = prosort_release_record (ps_ctx, buf, REC_LEN); if (rc < 0) { print_err_msg (rc); exit (rc); } } /* 레코드 입력 완료 */ prosort_release_end (ps_ctx); do { char outbuf[REC_LEN]; char *outbufs[1]; unsigned int len = REC_LEN; outbufs[0] = outbuf; rc = prosort_return_record (ps_ctx, outbufs, &len); if (rc < 0) { print_err_msg (rc); exit (rc); } if (len == 0) break; printf ("%s\n", outbuf); } while (1); prosort_end (ps_ctx); return 0; }
2.2.5. prosort_release_end
SORT 연산을 할 때 데이터 입력이 끝났음을 나타내는 함수이다.
-
프로토타입
int prosort_release_end(void *prosort_context);
-
파라미터
파라미터 설명 *prosort_context
prosort_setup 함수에서 생성한 컨텍스트를 전달한다.
-
예제
#include <stdio.h> #include <stdlib.h> #include "prosort.h" static void print_err_msg(int ec) { fprintf(stderr,"Error[%d]:\n", ec); fprintf(stderr,"%s\n", ps_err_code_to_cause(ec)); fprintf(stderr,"%s\n", ps_err_code_to_action(ec)); fprintf(stderr,"%s\n", ps_err_get_last_msg()); } /* 16byte 레코드 */ #define REC_LEN 16 #define RAND (char) (rand() % 24) + 'A' int main(int argc, char **argv) { int i = 0; int j = 0; int rc = 0; void *ps_ctx; char buf[REC_LEN]; const char *script = "MEMORY 100M\n" "DATASIZE 100M\n" "DEFREC FIXED, SIZE=16\n" "SORT FIELDS = (1,8,CH,A)\n"; /* 스크립트 설정 */ rc = prosort_setup (script, NULL, 0, &ps_ctx); if (rc < 0) { print_err_msg (rc); exit (rc); } /* 레코드 입력 */ for (i = 0; i < 100; i++) { for (j = 0; j < REC_LEN - 1; j++) buf[j] = RAND; buf[j] = 0; rc = prosort_release_record (ps_ctx, buf, REC_LEN); if (rc < 0) { print_err_msg (rc); exit (rc); } } /* 레코드 입력 완료 */ prosort_release_end (ps_ctx); do { char outbuf[REC_LEN]; char *outbufs[1]; unsigned int len = REC_LEN; outbufs[0] = outbuf; rc = prosort_return_record (ps_ctx, outbufs, &len); if (rc < 0) { print_err_msg (rc); exit (rc); } if (len == 0) break; printf ("%s\n", outbuf); } while (1); prosort_end (ps_ctx); return 0; }
2.2.6. prosort_return_record
연산의 결과를 레코드 건별로 가져오는 함수이다. 출력은 OUTFIL로 인해 여러 개가 나올 수 있으므로, 버퍼의 배열로 가져온다. 0 번째는 SORTOUT (OUTFIL을 수행하지 않은 출력)이 나오며, 스크립트에 정의된 OUTFIL이 순서대로 출력된다.
-
프로토타입
int prosort_return_record(void *prosort_context, char **output_buffer, unsigned int *output_buffer_length); -
파라미터
파라미터 설명 *prosort_context
prosort_setup 함수에서 생성한 컨텍스트를 전달한다.
**output_buffer
출력 레코드를 가져올 버퍼 주소의 배열이다.
*output_buffer_length
출력 레코드의 크기를 저장할 배열이다.
-
예제
#include <stdio.h> #include <stdlib.h> #include "prosort.h" static void print_err_msg(int ec) { fprintf(stderr,"Error[%d]:\n", ec); fprintf(stderr,"%s\n", ps_err_code_to_cause(ec)); fprintf(stderr,"%s\n", ps_err_code_to_action(ec)); fprintf(stderr,"%s\n", ps_err_get_last_msg()); } /* 16byte 레코드 */ #define REC_LEN 16 #define RAND (char) (rand() % 24) + 'A' int main(int argc, char **argv) { int i = 0; int j = 0; int rc = 0; void *ps_ctx; char buf[REC_LEN]; const char *script = "MEMORY 100M\n" "DATASIZE 100M\n" "DEFREC FIXED, SIZE=16\n" "SORT FIELDS = (1,8,CH,A)\n"; /* 스크립트 설정 */ rc = prosort_setup (script, NULL, 0, &ps_ctx); if (rc < 0) { print_err_msg (rc); exit (rc); } /* 레코드 입력 */ for (i = 0; i < 100; i++) { for (j = 0; j < REC_LEN - 1; j++) buf[j] = RAND; buf[j] = 0; rc = prosort_release_record (ps_ctx, buf, REC_LEN); if (rc < 0) { print_err_msg (rc); exit (rc); } } /* 레코드 입력 완료 */ prosort_release_end (ps_ctx); do { char outbuf[REC_LEN]; char *outbufs[1]; unsigned int len = REC_LEN; outbufs[0] = outbuf; rc = prosort_return_record (ps_ctx, outbufs, &len); if (rc < 0) { print_err_msg (rc); exit (rc); } if (len == 0) break; printf ("%s\n", outbuf); } while (1); prosort_end (ps_ctx); return 0; }
2.2.7. prosort_end
모든 연산에 사용한 리소스를 반환하는 함수이다.
-
프로토타입
int prosort_end(void *prosort_context);
-
파라미터
파라미터 설명 *prosort_context
prosort_setup 함수에서 생성한 컨텍스트를 전달한다.
-
예제
#include <stdio.h> #include <stdlib.h> #include "prosort.h" static void print_err_msg(int ec) { fprintf(stderr,"Error[%d]:\n", ec); fprintf(stderr,"%s\n", ps_err_code_to_cause(ec)); fprintf(stderr,"%s\n", ps_err_code_to_action(ec)); fprintf(stderr,"%s\n", ps_err_get_last_msg()); } /* 16byte 레코드 */ #define REC_LEN 16 #define RAND (char) (rand() % 24) + 'A' int main(int argc, char **argv) { int i = 0; int j = 0; int rc = 0; void *ps_ctx; char buf[REC_LEN]; const char *script = "MEMORY 100M\n" "DATASIZE 100M\n" "DEFREC FIXED, SIZE=16\n" "SORT FIELDS = (1,8,CH,A)\n"; /* 스크립트 설정 */ rc = prosort_setup (script, NULL, 0, &ps_ctx); if (rc < 0) { print_err_msg (rc); exit (rc); } /* 레코드 입력 */ for (i = 0; i < 100; i++) { for (j = 0; j < REC_LEN - 1; j++) buf[j] = RAND; buf[j] = 0; rc = prosort_release_record (ps_ctx, buf, REC_LEN); if (rc < 0) { print_err_msg (rc); exit (rc); } } /* 레코드 입력 완료 */ prosort_release_end (ps_ctx); do { char outbuf[REC_LEN]; char *outbufs[1]; unsigned int len = REC_LEN; outbufs[0] = outbuf; rc = prosort_return_record (ps_ctx, outbufs, &len); if (rc < 0) { print_err_msg (rc); exit (rc); } if (len == 0) break; printf ("%s\n", outbuf); } while (1); prosort_end (ps_ctx); return 0; }
2.2.8. prosort_get_error_number
에러가 발생했을 때 에러 번호를 가져오는 함수이다.
-
프로토타입
int prosort_get_error_number(void *prosort_context);
-
파라미터
파라미터 설명 *prosort_context
prosort_setup 함수에서 생성한 컨텍스트를 전달한다.
-
예제
int main(int argc, char **argv) { int rc; void *ps_ctx; const char *script = "DEFREC FIXED,SIZE=150 \n" "DATASIZE 2M \n" "MEMORY 512M \n" "WORKSPACE = (./) \n" "SORT FIELDS=(1,2,A),FORMAT=BI \n" "INCLUDE COND=(1,2,CH,EQ,C'12',OR,1,2,CH,EQ,C'22',OR,1,2,CH,EQ,C'32') \n" "OUTFIL FNAMES=OUT1 \n"; rc = prosort_setup(script, NULL, 0, &ps_ctx); if(rc < 0) { fprintf(stderr, "Error number is %d\n", prosort_get_error_number(ps_ctx)); } ... }
2.2.9. prosort_get_error_message
에러가 발생했을 때 에러 메시지를 가져오는 함수이다.
-
프로토타입
int prosort_get_error_message(void *prosort_context, char *error_message_buffer, unsigned int *error_message_length); -
파라미터
파라미터 설명 *prosort_context
prosort_setup 함수에서 생성한 컨텍스트를 전달한다.
*error_message_buffer
에러 메시지를 가져올 버퍼의 주소이다.
*error_message_length
에러 메시지의 길이이다.
-
예제
#define ERR_MSG_MAXLEN 1024 int main(int argc, char **argv) { int rc; void *ps_ctx; char *err_msg; unsigned int err_msg_len; const char *script = "DEFREC FIXED,SIZE=150 \n" "DATASIZE 2M \n" "MEMORY 512M \n" "WORKSPACE = (./) \n" "SORT FIELDS=(1,2,A),FORMAT=BI \n" "INCLUDE COND=(1,2,CH,EQ,C'12',OR,1,2,CH,EQ,C'22',OR,1,2,CH,EQ,C'32') \n" "OUTFIL FNAMES=OUT1 \n"; err_msg = (char *)malloc(sizeof(char) * ERR_MSG_MAXLEN); err_msg_len = ERR_MSG_MAXLEN; rc = prosort_setup(script, NULL, 0, &ps_ctx); if(rc < 0) { prosort_get_error_message(ps_ctx, err_msg, &err_msg_len); fprintf(stderr, "Error message is %s\n", err_msg); } ... }