<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Cradicle Explorer</title>
    <link href="/css/bootstrap/bootstrap.min.css" rel="stylesheet">
    <style>
      .form-control-dark::placeholder {
          color: #aaa;
          opacity: 1;
      }
    </style>
    <link rel="stylesheet" href="/assets/fontawesome/css/all.min.css">
    <link rel="icon" type="image/png" href="/favicon.png">


                <link href="/css/dashboard.css" rel="stylesheet">
                </head>
                <body>
                <header class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0 shadow">
                  <a class="navbar-brand col-md-3 col-lg-2 me-0 px-3 fs-6" href="/">Cradicle Explorer</a>
                  <button class="navbar-toggler position-absolute d-md-none collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#sidebarMenu" aria-controls="sidebarMenu" aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                  </button>
                  <form method="get" action="/cgi-bin/main" style="width:100%;"><input class="form-control form-control-dark w-100 rounded-0 border-0" type="text" name="q" placeholder="Search repos" aria-label="Search"></form>
                  <div class="navbar-nav flex-row">
                    <div class="nav-item text-nowrap">
                      <a class="nav-link px-3 active" href="/cgi-bin/repo?id=z2TnUbAvioTdwNUMynX3wB2zzP73L">libflashlight</a>
                    </div>
                  </div>
                </header>
                <div class="container-fluid">
                  <div class="row">
                    <nav id="sidebarMenu" class="col-md-3 col-lg-2 d-md-block bg-dark sidebar collapse">
                      <div class="position-sticky pt-3 sidebar-sticky">
                        <ul class="nav flex-column">
                          <li class="nav-item">
                            <a class="nav-link active" href="/cgi-bin/repo?id=z2TnUbAvioTdwNUMynX3wB2zzP73L">
                              <i class="align-text-bottom fa-solid fa-info"></i>
                              Info
                            </a>
                          </li>
                          <li class="nav-item">
                            <a class="nav-link" href="/cgi-bin/repo?id=z2TnUbAvioTdwNUMynX3wB2zzP73L&issue=list">
                              <i class="align-text-bottom fa-solid fa-layer-group"></i>
                              Issues
                            </a>
                          </li>
                          <li class="nav-item">
                            <a class="nav-link" href="/cgi-bin/repo?id=z2TnUbAvioTdwNUMynX3wB2zzP73L&patch=list">
                              <i class="align-text-bottom fa-solid fa-vest-patches"></i>
                              Patches
                            </a>
                          </li>
                          <li class="nav-item">
                            <a class="nav-link" href="/cgi-bin/repo?id=z2TnUbAvioTdwNUMynX3wB2zzP73L&wallet=list">
                              <i class="align-text-bottom fa-solid fa-wallet"></i>
                              Wallets
                            </a>
                          </li>
                          <li class="nav-item">
                            <a class="nav-link" href="/cgi-bin/repo?id=z2TnUbAvioTdwNUMynX3wB2zzP73L&source=.">
                              <i class="align-text-bottom fa-solid fa-code"></i>
                              Source
                            </a>
                          </li>
                        <h6 class="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted text-uppercase">
                          <span></span>
                        </h6>
                        <ul class="nav flex-column mb-2">
                        
                        </ul>
                      </div>
                    </nav>
                <main class="col-md-9 ms-sm-auto col-lg-10">
                  <div class="container px-1 py-3">
        

    <div class="list-group">
    <div class="list-group-item">
    <div style="font-size:1.3rem;">libflashlight</div>
    <div class="repo-item">A C library to build a newline index and do lookups on files of an arbitrary size.</div>
    <div>rad:z2TnUbAvioTdwNUMynX3wB2zzP73L</div>
    </div>
    <div class="list-group-item">
    <div>Visibility</div>
    <div class="repo-item">public</div>
    </div>
    <div class="list-group-item">
    <div>Delegates</div><div class="repo-item">did:key:z6MkvBFWpEgA26wN2MbAzL4EJtrGXUmJ7fsNsCNU4pBjJ3j9</div>
    </div>
    <div class="list-group-item">
    <div>Default branch</div>
    <div><span class="repo-item">main &#8594 8cc4cbe942f50d6a3cbcae4a81e8c44756353bc8</span> (Sat Feb  3 22:26:14 2024)</div>
    </div>
    <div class="list-group-item">
    <div>Threshold</div>
    <div class="repo-item">1</div>
    </div>
    </div>
    
        <div class="list-group mt-3">
        <div class="list-group-item">
        <div class="mb-2" style="font-weight:bold;"><i class="fa-solid fa-book"></i> README.md</div>
        <pre style="margin:0; font-size:0.85rem; overflow-x:auto; color:#fafafa;"># libflashlight

A library to build a newline index on files of an arbitrary size.

libflashlight indexes a file in both multiple threads and concurrently.
It is designed to run on machines with multiple cores.
Once a target file is indexed, abitrary lookups based on line numbers can be made.

Supported operating systems are currently MacOSX and Linux.  Windows support may be added in the future.

## Build from source

This library can be built with [xmake](https://xmake.io)

* Run tests: `xmake build test`
* Run valgrind in Ubuntu container (macosx reports false positives): `docker-compose up`
* Configure for release or debug: `xmake f -m release -k &lt;shared|static&gt;`
* Build lib: `xmake build lib`
* Install lib: `xmake install lib`
* Generate the docs using doxygen
  * `git submodule init`
  * `git submodule update` 
  * `xmake doxygen`

Build artifacts are located in `build/&lt;platform&gt;/&lt;arch&gt;/&lt;mode&gt;`

## Usage

```c
#include &lt;flashlight.h&gt;

void on_progress(double progress, void* payload)
{
  printf(&quot;loading: %f...\n&quot;, progress);
}

int main(void)
{
  f_indexer config = {
    .filename = &quot;/some/file/to/index&quot;,
    .lookup_dir = &quot;dir/to/store/.index&quot;
    .threads = 6,
    .concurrency = 50,
    .buffer_size = 10000,
    .max_bytes_per_iteration = 10000000000,
    .on_progress = progress_cb
    .payload = NULL
  };

  // index the target file
  f_index* index = f_index_text_file(config);

  char* lookup
  // lookup 5 lines starting at line 9 million.
  if (f_index_lookup(&amp;lookup, index, 9000000, 5) == -1)
  {
    printf(&quot;failure\n&quot;);
    return 1;
  };

  // do something with the lookup
  printf(&quot;%s\n&quot;, lookup);
  free(lookup);

  // free the index when done
  f_index_free(&amp;index);
  return 0;
}

```
### Searching against an index with regex

Searching is possible using PCRE2 regex.

Search results propogate to a callback when they are matched, and the calling code can 
choose to store these how it wishes.

An example using https://github.com/tidwall/btree.c

```c
#include &lt;flashlight.h&gt;
#include &lt;btree.c&gt;

void search_progress(double progress)
{
  printf(&quot;Search progress (%lf)\n&quot;, progress);
}

int search_result_compare(const void* a, const void* b, void* udata)
{
  f_search_result* sa = a;
  f_search_result* sb = b;
  return sa-&gt;line_number &gt; sb-&gt;line_number ? 1 : -1;
}

void append_search_result(f_search_result* res, void* payload)
{
  struct btree* results = payload;
  if (btree_set(results, res) != NULL) exit(1);
}

int main(void)
{
  // seed rand so index filenames are random...
  srand(time(0));

  f_indexer i = {
    .filename = &quot;some/file/to/index.txt&quot;,
    .lookup_dir = &quot;.flashlight&quot;,
    .threads = 6,
    .concurrency = 50,
    .buffer_size = 50000,
    .max_bytes_per_iteration = 10000000000,
    .on_progress = NULL,
    .payload = NULL
  };

  f_index* index = f_index_text_file(i);

  // Search against index
  struct btree* results = btree_new(sizeof(f_search_result), 0, search_result_compare, NULL);

  f_searcher searcher = {
    .regex = &quot;^car&quot;,
    .index = index,
    .threads = 6,
    .line_buffer = 1000,
    .on_progress = search_progress,
    .progress_payload = NULL,
    .on_result = append_search_result,
    .result_payload = results
  };

  if (f_index_search(searcher) != 0)
  {
    printf(&quot;search failed\n&quot;);
  }

  f_search_result** res;
  while (res = btree_pop_min(results))
  {
    printf(&quot;[%zu] - %s\n&quot;, res-&gt;line_number, res-&gt;str);
  }

  btree_free(results);
  f_index_free(&amp;index);

  return 0;
}
```

## Development

When adding new files
* the header file can be added to `genheader`
* run `genheader` to rebuild `flashlight.h`</pre>
        </div>
        </div>

</div>
</main>
</div>
</div>


</body>
</html>

