Преглед изворни кода

Rewrite C bsearch.

Working fine, but is not as optimized and fast as I hoped.
Probably can get very good speeds for API if translation
is stored in memory, which would require some changes.
master
Daniel пре 7 месеци
родитељ
комит
4fe38ae545
4 измењених фајлова са 80 додато и 66 уклоњено
  1. +6
    -6
      Makefile
  2. +57
    -41
      bsearch.c
  3. +2
    -2
      bsearch.h
  4. +15
    -17
      test.c

+ 6
- 6
Makefile Прегледај датотеку

@@ -2,12 +2,12 @@ t ?= web
dir ?= ../

default:
@$(CC) -I$(dir) $(dir)/biblec/biblec.c bsearch.c test.c -o test.out
@./test.out
@rm -rf *.out
$(CC) -I$(dir) $(dir)/biblec/biblec.c bsearch.c test.c -o test.out
./test.out
rm -rf *.out

# make setup f=kjv
setup:
-@cd biblec; mkdir bibles
@cd biblec/bibles; wget http://api.heb12.com/translations/biblec/$(t).i
@cd biblec/bibles; wget http://api.heb12.com/translations/biblec/$(t).t
-cd biblec; mkdir bibles
cd biblec/bibles; wget http://api.heb12.com/translations/biblec/$(t).i
cd biblec/bibles; wget http://api.heb12.com/translations/biblec/$(t).t

+ 57
- 41
bsearch.c Прегледај датотеку

@@ -44,7 +44,7 @@ int bsearch_getVerse(char buffer[], int line, struct BiblecTranslation *translat
line -= result;

// (verses start at zero)
line++;
//line++;

// TODO: return as a structure instead of a
// possible useless string
@@ -114,56 +114,72 @@ int getHits(int hits[], char string[], struct BiblecTranslation *translation) {
return hit;
}

int bsearch_open(char words[][BSEARCH_MAX_WORD], int length, int result[],
struct BiblecTranslation *translation) {
int hit1 = getHits(result, words[0], translation);
if (hit1 == -1) {
return -1;
}
int bsearch_open(char mySearch[][BSEARCH_MAX_WORD], int length,
int hits[BSEARCH_MAX_HITS], struct BiblecTranslation *translation) {
int hiti = 0;

char buffer[6000];
char word[64];
int line = 0;

if (length == 1) {
return hit1;
FILE *verseFile = fopen(translation->location, "r");
if (verseFile == NULL) {
return -1;
}

int m = 0;
for (int w = 1; w < length; w++) {
if (strlen(words[w]) <= BSEARCH_MIN_WORD) {
continue;
}
int *hits2 = malloc(BSEARCH_MAX_HITS);
int hit2 = getHits(hits2, words[w], translation);
if (hit2 == -1) {
free(hits2);
return -1;
}
while (fgets(buffer, VERSE_LENGTH, verseFile) != NULL) {
int match[1024] = {0};
int wc = 0;
int wordi = 0;
for (int c = 0; buffer[c] != '\0'; c++) {
// Make sure this is an alphabetical character
if (buffer[c] >= 'a' && buffer[c] <= 'z') {
word[wc] = buffer[c];
wc++;
} else if (buffer[c] >= 'A' && buffer[c] <= 'Z') {
// Make character lowercase
word[wc] = buffer[c] + ('a' - 'A');
wc++;
} else if (buffer[c] == ' ' || buffer[c] == '\n') {
// Quit if no useful data was read
if (wc <= BSEARCH_MIN_WORD) {
word[wc] = '\0';
wc = 0;
continue;
}
// Reset once we encounter new line
word[wc] = '\0';
wc = 0;

// Match last word with current word
m = 0;
int *temp = malloc(BSEARCH_MAX_HITS);
for (int x = 0; x < hit1; x++) {
for (int y = 0; y < hit2; y++) {
if (result[x] == hits2[y]) {
temp[m] = result[x];
m++;

// Max results reached, don't quit, but
// kill matching silently
if (m > BSEARCH_MAX_HITS) {
free(hits2);
free(temp);
return m;
for (int i = 0; i < length; i++) {
if (!strcmp(mySearch[i], word)) {
match[i]++;
break;
}
}

wordi++;
}
}
line++;

// Copy for matching next
memcpy(result, temp, sizeof(int) * m);
int fullMatch = 1;
for (int i = 0; i < length; i++) {
if (!match[i]) {
fullMatch = 0;
}
}

free(hits2);
free(temp);
if (fullMatch) {
hits[hiti] = line;
hiti++;
}
}

return m;
fclose(verseFile);

return hiti;
}

+ 2
- 2
bsearch.h Прегледај датотеку

@@ -8,7 +8,7 @@
int bsearch_getVerse(char buffer[], int line,
struct BiblecTranslation *translation);

int bsearch_open(char words[][BSEARCH_MAX_WORD], int length, int result[],
struct BiblecTranslation *translation);
int bsearch_open(char mySearch[][BSEARCH_MAX_WORD], int length,
int hits[BSEARCH_MAX_HITS], struct BiblecTranslation *translation);

#endif

+ 15
- 17
test.c Прегледај датотеку

@@ -12,7 +12,7 @@ struct BiblecTranslation translation;
int main() {
int tryFile = biblec_parse(
&translation,
"/home/dan/.local/share/heb12/web.i"
"/home/daniel/.local/share/heb12/web.i"
);

if (tryFile) {
@@ -22,34 +22,32 @@ int main() {
clock_t start = clock();

char mySearch[][BSEARCH_MAX_WORD] = {
"created",
"heavens",
"earth"
"for",
"god",
"loved",
"world",
};

int *result = malloc(BSEARCH_MAX_HITS);
int c = bsearch_open(
mySearch,
sizeof(mySearch) / sizeof(mySearch[0]),
result,
&translation
);
int *hits = malloc(BSEARCH_MAX_HITS * sizeof(int));

printf("Result: %d\n", c);
int c = bsearch_open(mySearch,
sizeof(mySearch) / sizeof(mySearch[0]), hits, &translation);

if (c == -1) {
return -1;
puts("Err");
return 1;
}

char buffer[128];
char buffer[1024];
for (int i = 0; i < c; i++) {
bsearch_getVerse(buffer, result[i], &translation);
printf("%d\t%s\n", result[i], buffer);
bsearch_getVerse(buffer, hits[i], &translation);
printf("%d\t%s\n", hits[i], buffer);
}

free(hits);

double elapsed = (double)(clock() - start) / CLOCKS_PER_SEC;
printf("Done in %f seconds.\n", elapsed);

free(result);
return 0;
}

Loading…
Откажи
Сачувај