/ src / indexer.c
indexer.c
  1  #ifndef FLASHLIGHT_INDEXER
  2  #define FLASHLIGHT_INDEXER
  3  #include "indexer.h"
  4  
  5  int f_indexer_chunks_init(f_indexer_chunks** out, int concurrency, size_t buffer_size, size_t total_bytes, size_t from, size_t to)
  6  {
  7    f_indexer_chunks* init = malloc(sizeof(*init));
  8    if (init == NULL)
  9    {
 10      return -1;
 11    }
 12  
 13    size_t bytes_count = to - from;
 14  
 15    unsigned int chunks_count = (unsigned int) ceil(bytes_count / (double) (buffer_size));
 16  
 17    if (chunks_count == 0)
 18    {
 19      concurrency = 1;
 20    }
 21    else if (concurrency > chunks_count)
 22    {
 23      concurrency = (int) chunks_count;
 24    }
 25  
 26    init->concurrency = concurrency;
 27    init->len = chunks_count;
 28    init->chunks = malloc(sizeof(f_indexer_chunk*) * chunks_count);
 29  
 30    if (init->chunks == NULL)
 31    {
 32      free(init);
 33      return -1;
 34    }
 35  
 36    for(int cc=0; cc<chunks_count; cc++)
 37    {
 38      size_t start_position = from + (cc * buffer_size);
 39  
 40      if (start_position + buffer_size > bytes_count + from)
 41      {
 42        buffer_size = (bytes_count + from) - start_position;
 43      }
 44  
 45      f_indexer_chunk* chunk = malloc(sizeof(f_indexer_chunk));
 46      if (chunk == NULL)
 47      {
 48        free(init->chunks);
 49        free(init);
 50        return -1;
 51      }
 52  
 53      chunk->index = cc;
 54      chunk->from = start_position;
 55      chunk->count = buffer_size;
 56  
 57      init->chunks[cc] = chunk;
 58    }
 59  
 60    *out = init;
 61    return 0;
 62  }
 63  
 64  void f_indexer_chunks_free(f_indexer_chunks* index)
 65  {
 66    for (int i=0; i<index->len; i++)
 67    {
 68      free(index->chunks[i]);
 69    }
 70  
 71    free(index->chunks);
 72    free(index);
 73    index = NULL;
 74  }
 75  
 76  int f_indexer_threads_init(f_indexer_threads** out, int threads, size_t total_bytes_count, size_t buffer_size, size_t offset)
 77  {
 78    f_indexer_threads* init = malloc(sizeof(*init));
 79  
 80    if (init == NULL)
 81    {
 82      return -1;
 83    }
 84  
 85    unsigned int chunks_count = (unsigned int) ceil(total_bytes_count / (double) buffer_size);
 86  
 87    if (chunks_count == 0)
 88    {
 89      // 1 thread/buffer can open this file.
 90      threads = 1;
 91    }
 92    else if (threads > chunks_count)
 93    {
 94      // small files.
 95      threads = (int) chunks_count;
 96    }
 97  
 98    // established number of threads, let's allocate.
 99    init->len = threads;
100    init->threads = malloc(sizeof(f_indexer_thread) * threads);
101  
102    if (init->threads == NULL)
103    {
104      free(init);
105      return -1;
106    }
107  
108    unsigned long int pages = (unsigned long int) ceil(total_bytes_count / threads);
109  
110    for (int i=0; i<threads; i++)
111    {
112      unsigned long int start_position = (i * pages);
113      start_position += i;
114  
115      if (start_position + pages > total_bytes_count)
116      {
117        pages = (total_bytes_count - start_position);
118      }
119  
120      unsigned long int to = start_position + pages;
121  
122      f_indexer_thread index = {
123        .from = start_position + offset,
124        .to = to + offset,
125        .total_bytes_count = total_bytes_count,
126        .buffer_size = buffer_size,
127      };
128  
129      init->threads[i] = index;
130    }
131  
132    *out = init;
133    return 0;
134  }
135  
136  void f_indexer_threads_free(f_indexer_threads* index)
137  {
138    free(index->threads);
139    free(index);
140  }
141  
142  #endif