Compare commits

..

No commits in common. "79c31589748f88dc50d01be89c3da905518910c5" and "d64fec048fbfebebc1629a3d69a3dbb84240fe07" have entirely different histories.

8 changed files with 26 additions and 96 deletions

View File

@ -7,10 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased](https://git.rustybever.be/Chewing_Bever/lander/src/branch/dev) ## [Unreleased](https://git.rustybever.be/Chewing_Bever/lander/src/branch/dev)
## Fixed
* Failed uploads now no longer leave behind a partial entry file
## [0.2.1](https://git.rustybever.be/Chewing_Bever/lander/src/tag/0.2.1) ## [0.2.1](https://git.rustybever.be/Chewing_Bever/lander/src/tag/0.2.1)
### Added ### Added

View File

@ -51,8 +51,6 @@ lnm_http_step_err lander_post_paste_secure(lnm_http_conn *conn);
lnm_http_step_err lander_stream_body_to_entry(lnm_http_conn *conn); lnm_http_step_err lander_stream_body_to_entry(lnm_http_conn *conn);
lnm_http_step_err lander_commit_entry(lnm_http_conn *conn);
lnm_http_step_err lander_post_redirect_body_to_attr(lnm_http_conn *conn); lnm_http_step_err lander_post_redirect_body_to_attr(lnm_http_conn *conn);
lnm_http_step_err lander_remove_entry(lnm_http_conn *conn); lnm_http_step_err lander_remove_entry(lnm_http_conn *conn);

View File

@ -159,15 +159,6 @@ lsm_error lsm_store_open_read(lsm_entry_handle **out, lsm_store *store,
lsm_error lsm_store_open_write(lsm_entry_handle **out, lsm_store *store, lsm_error lsm_store_open_write(lsm_entry_handle **out, lsm_store *store,
const lsm_str *key); const lsm_str *key);
/**
* Commit any changes to the persistent storage. Any changes, insertions or
* deletions that occured without a commit are reverted when the handle is
* closed.
*
* @param handle handle to the entry
*/
lsm_error lsm_entry_commit(lsm_entry_handle *handle);
/** /**
* Close an open entry handle. * Close an open entry handle.
* *

View File

@ -157,8 +157,7 @@ lsm_error lsm_entry_data_open_read(lsm_entry_handle *handle);
lsm_error lsm_entry_data_open_write(lsm_entry_handle *handle); lsm_error lsm_entry_data_open_write(lsm_entry_handle *handle);
/** /**
* Remove the entry's data file if present and close its handle. Any uncommitted * Remove the entry's data file if present and close its handle.
* changes will be reverted.
* *
* @param handle handle to the entry * @param handle handle to the entry
*/ */

View File

@ -1,5 +1,3 @@
#include <stdint.h>
#include "lsm/store_internal.h" #include "lsm/store_internal.h"
static lsm_error lsm_fwrite(uint64_t *sum, FILE *f, uint64_t size, static lsm_error lsm_fwrite(uint64_t *sum, FILE *f, uint64_t size,
@ -127,10 +125,16 @@ lsm_error lsm_entry_disk_insert(lsm_entry_handle *handle) {
return res; return res;
} }
static lsm_error lsm_idx_zero_block(lsm_store *store, uint64_t pos) { // Marking an entry as removed in the idx file is simply setting the length of
// its entry to zero
lsm_error lsm_entry_disk_remove(lsm_entry_handle *handle) {
lsm_store *store = handle->store;
const lsm_entry *entry = handle->wrapper->entry;
pthread_mutex_lock(&store->idx.lock); pthread_mutex_lock(&store->idx.lock);
lsm_error res = lsm_fseek(store->idx.f, pos); lsm_error res =
lsm_fseek(store->idx.f, entry->idx_file_offset + sizeof(uint64_t));
if (res != lsm_error_ok) { if (res != lsm_error_ok) {
pthread_mutex_unlock(&store->idx.lock); pthread_mutex_unlock(&store->idx.lock);
@ -149,29 +153,7 @@ static lsm_error lsm_idx_zero_block(lsm_store *store, uint64_t pos) {
fflush(store->idx.f); fflush(store->idx.f);
return lsm_error_ok;
}
// Marking an entry as removed in the idx file is simply setting the length of
// its entry to zero
lsm_error lsm_entry_disk_remove(lsm_entry_handle *handle) {
const lsm_entry *entry = handle->wrapper->entry;
LSM_RES(lsm_idx_zero_block(handle->store,
entry->idx_file_offset * sizeof(uint64_t)));
LSM_RES(lsm_entry_data_remove(handle)); LSM_RES(lsm_entry_data_remove(handle));
return lsm_error_ok; return lsm_error_ok;
} }
lsm_error lsm_entry_disk_update(lsm_entry_handle *handle) {
// An update is implemented by reinserting the entry at the end of the db file
uint64_t old_idx_index = handle->wrapper->entry->idx_file_offset;
// TODO is there any way we can make this atomic? If the zero write to the
// index file fails, there are two entries in the db file for the same key.
LSM_RES(lsm_entry_disk_insert(handle));
LSM_RES(lsm_idx_zero_block(handle->store, old_idx_index * sizeof(uint64_t)));
return lsm_error_ok;
}

View File

@ -58,51 +58,35 @@ lsm_error lsm_entry_handle_init(lsm_entry_handle **out) {
return lsm_error_ok; return lsm_error_ok;
} }
lsm_error lsm_entry_commit(lsm_entry_handle *handle) {
uint8_t state_new = handle->states & lsm_entry_handle_state_new;
uint8_t state_removed = handle->states & lsm_entry_handle_state_removed;
uint8_t state_updated = handle->states & lsm_entry_handle_state_updated;
// Clean new entry
if (state_new && !state_removed) {
LSM_RES(lsm_entry_disk_insert(handle));
}
// Previously stored entry that needs to be removed; should be removed from db
// file as well
else if (state_removed && !state_new) {
LSM_RES(lsm_entry_disk_remove(handle));
lsm_entry_free(handle->wrapper->entry);
handle->wrapper->entry = NULL;
} else if (state_updated && !(state_new || state_removed)) {
LSM_RES(lsm_entry_disk_update(handle));
}
// Reset states after committing current changes
handle->states = 0;
return lsm_error_ok;
}
void lsm_entry_close(lsm_entry_handle *handle) { void lsm_entry_close(lsm_entry_handle *handle) {
if (handle->f != NULL) { if (handle->f != NULL) {
fclose(handle->f); fclose(handle->f);
handle->f = NULL;
} }
uint8_t state_new = handle->states & lsm_entry_handle_state_new; bool state_new = handle->states & lsm_entry_handle_state_new;
bool state_removed = handle->states & lsm_entry_handle_state_removed;
/* bool state_updated = handle->states & lsm_entry_handle_state_updated; */ /* bool state_updated = handle->states & lsm_entry_handle_state_updated; */
// New entries create a wrapper in the trie that should be removed if not // Clean new entry
// committed if (state_new && !state_removed) {
if (state_new) { lsm_entry_disk_insert(handle);
}
// New entry that was removed before being written to disk; only its data file
// needs to be removed if present
else if (state_new && state_removed) {
lsm_entry_data_remove(handle); lsm_entry_data_remove(handle);
lsm_entry_free(handle->wrapper->entry); lsm_entry_free(handle->wrapper->entry);
handle->wrapper->entry = NULL; handle->wrapper->entry = NULL;
} }
// Previously stored entry that needs to be removed; should be removed from db
// file as well
else if (state_removed && !state_new) {
lsm_entry_disk_remove(handle);
// TODO rollback uncomitted updates lsm_entry_free(handle->wrapper->entry);
handle->wrapper->entry = NULL;
}
pthread_rwlock_unlock(&handle->wrapper->lock); pthread_rwlock_unlock(&handle->wrapper->lock);
free(handle); free(handle);
@ -344,6 +328,7 @@ lsm_error lsm_entry_data_open_read(lsm_entry_handle *handle) {
return lsm_error_ok; return lsm_error_ok;
} }
lsm_error lsm_entry_data_remove(lsm_entry_handle *handle) { lsm_error lsm_entry_data_remove(lsm_entry_handle *handle) {
const lsm_entry *entry = handle->wrapper->entry; const lsm_entry *entry = handle->wrapper->entry;

View File

@ -1,7 +1,6 @@
#include <string.h> #include <string.h>
#include "lnm/http/loop.h" #include "lnm/http/loop.h"
#include "lnm/log.h"
#include "lnm/loop.h" #include "lnm/loop.h"
#include "lander.h" #include "lander.h"
@ -26,12 +25,3 @@ lnm_http_step_err lander_stream_body_to_entry(lnm_http_conn *conn) {
? lnm_http_step_err_done ? lnm_http_step_err_done
: lnm_http_step_err_io_needed; : lnm_http_step_err_io_needed;
} }
lnm_http_step_err lander_commit_entry(lnm_http_conn *conn) {
lnm_http_loop_ctx *ctx = conn->ctx;
lander_ctx *c_ctx = ctx->c;
lsm_entry_commit(c_ctx->entry);
return lnm_http_step_err_done;
}

View File

@ -3,7 +3,6 @@
#include <time.h> #include <time.h>
#include "lnm/http/loop.h" #include "lnm/http/loop.h"
#include "lnm/http/route.h"
#include "lnm/log.h" #include "lnm/log.h"
#include "lander.h" #include "lander.h"
@ -31,64 +30,54 @@ lnm_http_loop *loop_init(lander_gctx *gctx, const char *api_key) {
lnm_http_router_add(&route, router, lnm_http_method_delete, "/:key"); lnm_http_router_add(&route, router, lnm_http_method_delete, "/:key");
lnm_http_route_step_append(route, lnm_http_loop_step_auth, false); lnm_http_route_step_append(route, lnm_http_loop_step_auth, false);
lnm_http_route_step_append(route, lander_remove_entry, false); lnm_http_route_step_append(route, lander_remove_entry, false);
lnm_http_route_step_append(route, lander_commit_entry, true);
lnm_http_router_add(&route, router, lnm_http_method_post, "/s/"); lnm_http_router_add(&route, router, lnm_http_method_post, "/s/");
lnm_http_route_step_append(route, lnm_http_loop_step_auth, false); lnm_http_route_step_append(route, lnm_http_loop_step_auth, false);
lnm_http_route_step_append(route, lander_post_redirect, false); lnm_http_route_step_append(route, lander_post_redirect, false);
lnm_http_route_step_append(route, lnm_http_loop_step_body_to_buf, false); lnm_http_route_step_append(route, lnm_http_loop_step_body_to_buf, false);
lnm_http_route_step_append(route, lander_post_redirect_body_to_attr, false); lnm_http_route_step_append(route, lander_post_redirect_body_to_attr, false);
lnm_http_route_step_append(route, lander_commit_entry, true);
lnm_http_router_add(&route, router, lnm_http_method_post, "/sl/"); lnm_http_router_add(&route, router, lnm_http_method_post, "/sl/");
lnm_http_route_step_append(route, lnm_http_loop_step_auth, false); lnm_http_route_step_append(route, lnm_http_loop_step_auth, false);
lnm_http_route_step_append(route, lander_post_redirect_secure, false); lnm_http_route_step_append(route, lander_post_redirect_secure, false);
lnm_http_route_step_append(route, lnm_http_loop_step_body_to_buf, false); lnm_http_route_step_append(route, lnm_http_loop_step_body_to_buf, false);
lnm_http_route_step_append(route, lander_post_redirect_body_to_attr, false); lnm_http_route_step_append(route, lander_post_redirect_body_to_attr, false);
lnm_http_route_step_append(route, lander_commit_entry, true);
lnm_http_router_add(&route, router, lnm_http_method_post, "/s/:key"); lnm_http_router_add(&route, router, lnm_http_method_post, "/s/:key");
lnm_http_route_step_append(route, lnm_http_loop_step_auth, false); lnm_http_route_step_append(route, lnm_http_loop_step_auth, false);
lnm_http_route_step_append(route, lander_post_redirect, false); lnm_http_route_step_append(route, lander_post_redirect, false);
lnm_http_route_step_append(route, lnm_http_loop_step_body_to_buf, false); lnm_http_route_step_append(route, lnm_http_loop_step_body_to_buf, false);
lnm_http_route_step_append(route, lander_post_redirect_body_to_attr, false); lnm_http_route_step_append(route, lander_post_redirect_body_to_attr, false);
lnm_http_route_step_append(route, lander_commit_entry, true);
lnm_http_router_add(&route, router, lnm_http_method_post, "/p/"); lnm_http_router_add(&route, router, lnm_http_method_post, "/p/");
lnm_http_route_step_append(route, lnm_http_loop_step_auth, false); lnm_http_route_step_append(route, lnm_http_loop_step_auth, false);
lnm_http_route_step_append(route, lander_post_paste, false); lnm_http_route_step_append(route, lander_post_paste, false);
lnm_http_route_step_append(route, lander_stream_body_to_entry, false); lnm_http_route_step_append(route, lander_stream_body_to_entry, false);
lnm_http_route_step_append(route, lander_commit_entry, true);
lnm_http_router_add(&route, router, lnm_http_method_post, "/pl/"); lnm_http_router_add(&route, router, lnm_http_method_post, "/pl/");
lnm_http_route_step_append(route, lnm_http_loop_step_auth, false); lnm_http_route_step_append(route, lnm_http_loop_step_auth, false);
lnm_http_route_step_append(route, lander_post_paste_secure, false); lnm_http_route_step_append(route, lander_post_paste_secure, false);
lnm_http_route_step_append(route, lander_stream_body_to_entry, false); lnm_http_route_step_append(route, lander_stream_body_to_entry, false);
lnm_http_route_step_append(route, lander_commit_entry, true);
lnm_http_router_add(&route, router, lnm_http_method_post, "/p/:key"); lnm_http_router_add(&route, router, lnm_http_method_post, "/p/:key");
lnm_http_route_step_append(route, lnm_http_loop_step_auth, false); lnm_http_route_step_append(route, lnm_http_loop_step_auth, false);
lnm_http_route_step_append(route, lander_post_paste, false); lnm_http_route_step_append(route, lander_post_paste, false);
lnm_http_route_step_append(route, lander_stream_body_to_entry, false); lnm_http_route_step_append(route, lander_stream_body_to_entry, false);
lnm_http_route_step_append(route, lander_commit_entry, true);
lnm_http_router_add(&route, router, lnm_http_method_post, "/f/"); lnm_http_router_add(&route, router, lnm_http_method_post, "/f/");
lnm_http_route_step_append(route, lnm_http_loop_step_auth, false); lnm_http_route_step_append(route, lnm_http_loop_step_auth, false);
lnm_http_route_step_append(route, lander_post_file, false); lnm_http_route_step_append(route, lander_post_file, false);
lnm_http_route_step_append(route, lander_stream_body_to_entry, false); lnm_http_route_step_append(route, lander_stream_body_to_entry, false);
lnm_http_route_step_append(route, lander_commit_entry, true);
lnm_http_router_add(&route, router, lnm_http_method_post, "/fl/"); lnm_http_router_add(&route, router, lnm_http_method_post, "/fl/");
lnm_http_route_step_append(route, lnm_http_loop_step_auth, false); lnm_http_route_step_append(route, lnm_http_loop_step_auth, false);
lnm_http_route_step_append(route, lander_post_file_secure, false); lnm_http_route_step_append(route, lander_post_file_secure, false);
lnm_http_route_step_append(route, lander_stream_body_to_entry, false); lnm_http_route_step_append(route, lander_stream_body_to_entry, false);
lnm_http_route_step_append(route, lander_commit_entry, true);
lnm_http_router_add(&route, router, lnm_http_method_post, "/f/:key"); lnm_http_router_add(&route, router, lnm_http_method_post, "/f/:key");
lnm_http_route_step_append(route, lnm_http_loop_step_auth, false); lnm_http_route_step_append(route, lnm_http_loop_step_auth, false);
lnm_http_route_step_append(route, lander_post_file, false); lnm_http_route_step_append(route, lander_post_file, false);
lnm_http_route_step_append(route, lander_stream_body_to_entry, false); lnm_http_route_step_append(route, lander_stream_body_to_entry, false);
lnm_http_route_step_append(route, lander_commit_entry, true);
lnm_http_loop_router_set(hl, router); lnm_http_loop_router_set(hl, router);