ok?
This commit is contained in:
parent
2b222dda0b
commit
3b1db93d74
5 changed files with 126 additions and 72 deletions
11
TODO.md
11
TODO.md
|
|
@ -1,14 +1,13 @@
|
||||||
- [ ] file operations
|
- [ ] file operations
|
||||||
- [ ] write to file (at index)
|
- [ ] write to file (at index)
|
||||||
- [ ] read from file (at index)
|
|
||||||
- [ ] print_file (maybe just calling cat???)
|
- [ ] print_file (maybe just calling cat???)
|
||||||
- [ ] a tape type - representing a file?
|
- [ ] a tape type - representing a file?
|
||||||
- [x] a record type - x1,x2,x3,x4,x5
|
- [x] a record type - x1,x2,x3,x4,x5
|
||||||
- [x] comparing records
|
- [x] comparing records
|
||||||
- [ ] natural merge sort
|
- [ ] buffer merge sort
|
||||||
- [ ] configuration
|
- [x] configuration
|
||||||
- [ ] cmd args - man getopts
|
- [x] cmd args - man getopts
|
||||||
- [ ] file input
|
- [x] file input
|
||||||
- [ ] keyboard input
|
- [x] keyboard input
|
||||||
- [ ] testing
|
- [ ] testing
|
||||||
- [ ] report
|
- [ ] report
|
||||||
|
|
|
||||||
121
main.c
121
main.c
|
|
@ -1,89 +1,124 @@
|
||||||
#include "record.h"
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#define MAX_RECORDS 1000
|
#define DEFAULT_NN 10000000
|
||||||
|
#define DEFAULT_N 1001
|
||||||
|
#define DEFAULT_B 10
|
||||||
#define END_PROGRAM -1
|
#define END_PROGRAM -1
|
||||||
#define SUCCESS 0
|
#define SUCCESS 0
|
||||||
#define ERROR -2
|
#define ERROR -2
|
||||||
|
|
||||||
void print_usage()
|
void print_usage()
|
||||||
{
|
{
|
||||||
printf("Usage: [-f filename] [-h]\n");
|
|
||||||
printf("Options:\n");
|
printf("Options:\n");
|
||||||
printf(" -f filename\tRead records from file\n");
|
printf(" -f [filename]\tRead/Generate records from [filename]\n");
|
||||||
printf(" -h\tShow this help message");
|
printf(" -r\t randomly generate N records, and process them\n");
|
||||||
|
printf(" -N [count]\tSet total number of records, default %d\n", DEFAULT_NN);
|
||||||
|
printf(" -n [count]\tSet blocking factor, default %d\n", DEFAULT_N);
|
||||||
|
printf(" -b [count]\tSet number of buffers, default %d\n", DEFAULT_B);
|
||||||
|
printf(" -h\tShow this help message\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// stream is function output
|
typedef struct
|
||||||
int process_args(int argc, char** argv, FILE** stream)
|
|
||||||
{
|
{
|
||||||
|
FILE* input;
|
||||||
|
bool generate_data;
|
||||||
|
bool manual_input;
|
||||||
|
int N; // number of records in a file
|
||||||
|
int b; // blocking factor
|
||||||
|
int n; // number of buffers
|
||||||
|
} options;
|
||||||
|
|
||||||
|
// reads args into opts
|
||||||
|
int process_args(int argc, char** argv, options* opts)
|
||||||
|
{
|
||||||
|
if (opts == NULL) {
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
opts->input = stdin;
|
||||||
|
opts->generate_data = false;
|
||||||
|
opts->manual_input = false;
|
||||||
|
opts->N = DEFAULT_NN;
|
||||||
|
opts->n = DEFAULT_N;
|
||||||
|
opts->b = DEFAULT_B;
|
||||||
char* filename = NULL;
|
char* filename = NULL;
|
||||||
int opt;
|
int opt;
|
||||||
while ((opt = getopt(argc, argv, "f:h")) != -1) {
|
while ((opt = getopt(argc, argv, "f:N:n:b:rhm")) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'f':
|
case 'f':
|
||||||
filename = optarg;
|
filename = optarg;
|
||||||
break;
|
break;
|
||||||
|
case 'r':
|
||||||
|
opts->generate_data = true;
|
||||||
|
break;
|
||||||
|
case 'N':
|
||||||
|
opts->N = atoi(optarg);
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
opts->n = atoi(optarg);
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
opts->b = atoi(optarg);
|
||||||
|
break;
|
||||||
|
case 'm':
|
||||||
|
opts->manual_input = true;
|
||||||
case 'h':
|
case 'h':
|
||||||
print_usage();
|
print_usage();
|
||||||
return END_PROGRAM;
|
return END_PROGRAM;
|
||||||
case '?':
|
case '?':
|
||||||
printf("invalid option, terminating\n");
|
fprintf(stderr, "invalid option, terminating\n");
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (filename != NULL) {
|
if (opts->manual_input == true && opts->generate_data == true) {
|
||||||
printf("%s\n", filename);
|
fprintf(stderr, "Incompatible arguments: mr, aborting\n");
|
||||||
*stream = fopen(filename, "r");
|
return ERROR;
|
||||||
if (!*stream) {
|
|
||||||
fprintf(stderr, "Error: Cannot open file '%s'\n", filename);
|
|
||||||
return END_PROGRAM;
|
|
||||||
}
|
}
|
||||||
|
if (filename == NULL) {
|
||||||
|
fprintf(stderr, "No file specified, aborting\n");
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
opts->input = fopen(filename, "a+");
|
||||||
|
if (!opts->input) {
|
||||||
|
fprintf(stderr, "Error: Cannot open file '%s'\n", filename);
|
||||||
|
return ERROR;
|
||||||
}
|
}
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_input(FILE* input)
|
void generate_file(options* opts)
|
||||||
{
|
{
|
||||||
record records[MAX_RECORDS];
|
|
||||||
int count = 0;
|
|
||||||
while (count < MAX_RECORDS) {
|
|
||||||
if (read_record(input, &records[count]) != SUCCESS) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
count++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("\nRead %d records\n", count);
|
void write_file(options* opts)
|
||||||
qsort(records, count, sizeof(record), compare_records);
|
{
|
||||||
printf("\nSorted records:\n");
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
printf("Record %d: ", i);
|
|
||||||
print_record(stdout, &records[i]);
|
|
||||||
printf("\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sort_file(options* opts)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
FILE* input = NULL;
|
options opts;
|
||||||
if (argc > 1) {
|
if (argc <= 1) {
|
||||||
int result = process_args(argc, argv, &input);
|
fprintf(stderr, "please specify input args\n");
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
int result = process_args(argc, argv, &opts);
|
||||||
if (result != SUCCESS) {
|
if (result != SUCCESS) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (input == NULL) {
|
if (opts.generate_data) {
|
||||||
printf("ok\n");
|
srand(time(0));
|
||||||
|
generate_file(&opts);
|
||||||
}
|
}
|
||||||
|
if (opts.manual_input) {
|
||||||
|
write_file(&opts);
|
||||||
}
|
}
|
||||||
if (input == NULL) {
|
sort_file(&opts);
|
||||||
printf("Enter records (format: a_0 a_1 a_2 a_3 a_4 x), or 'q' to quit:\n");
|
fclose(opts.input);
|
||||||
input = stdin;
|
|
||||||
}
|
|
||||||
process_input(input);
|
|
||||||
if (input != stdin) {
|
|
||||||
fclose(input);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
24
makefile
24
makefile
|
|
@ -1,25 +1,13 @@
|
||||||
# Compiler
|
build/main: main.c build
|
||||||
CC = clang
|
clang main.c -o build/main
|
||||||
CFLAGS = -Wall -Wextra -g
|
|
||||||
TARGET = file_sorting
|
|
||||||
BUILD_DIR = build
|
|
||||||
|
|
||||||
SRCS = main.c
|
build:
|
||||||
OBJS = $(SRCS:%.c=$(BUILD_DIR)/%.o)
|
mkdir -p build
|
||||||
|
|
||||||
$(BUILD_DIR)/$(TARGET): $(OBJS)
|
|
||||||
$(CC) $(CFLAGS) $(OBJS) -o $(BUILD_DIR)/$(TARGET)
|
|
||||||
|
|
||||||
$(BUILD_DIR)/%.o: %.c | $(BUILD_DIR)
|
|
||||||
$(CC) $(CFLAGS) -c $< -o $@
|
|
||||||
|
|
||||||
$(BUILD_DIR):
|
|
||||||
mkdir -p $(BUILD_DIR)
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf build
|
rm -rf build
|
||||||
|
|
||||||
run: $(BUILD_DIR)/$(TARGET)
|
run: build/main
|
||||||
$(BUILD_DIR)/$(TARGET)
|
build/main -f tests/1.in
|
||||||
|
|
||||||
.PHONY: clean run
|
.PHONY: clean run
|
||||||
|
|
|
||||||
8
record.h
8
record.h
|
|
@ -43,3 +43,11 @@ static inline int read_record(FILE* stream, record* out)
|
||||||
}
|
}
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void random_record(record* out)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
out->a[i] = rand();
|
||||||
|
}
|
||||||
|
out->x = rand();
|
||||||
|
}
|
||||||
|
|
|
||||||
24
tape.h
Normal file
24
tape.h
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
#pragma once
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int reads;
|
||||||
|
int writes;
|
||||||
|
FILE* file;
|
||||||
|
} tape;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
void* location;
|
||||||
|
int length;
|
||||||
|
int capacity;
|
||||||
|
} buffer;
|
||||||
|
|
||||||
|
// sorts the entire buffer
|
||||||
|
void quicksort(buffer* buff);
|
||||||
|
|
||||||
|
// reads [capacity] records
|
||||||
|
void read_buffer(buffer* buff, tape* tape);
|
||||||
|
// writes everything
|
||||||
|
void write_buffer(buffer* buff, tape* tape);
|
||||||
|
|
||||||
|
void clear_tape(tape* tape);
|
||||||
Loading…
Add table
Add a link
Reference in a new issue