aboutsummaryrefslogtreecommitdiff
path: root/ks_index.c
diff options
context:
space:
mode:
Diffstat (limited to 'ks_index.c')
-rw-r--r--ks_index.c66
1 files changed, 56 insertions, 10 deletions
diff --git a/ks_index.c b/ks_index.c
index c25f791..edfc7fa 100644
--- a/ks_index.c
+++ b/ks_index.c
@@ -202,6 +202,8 @@ hal_error_t hal_ks_index_find_range(hal_ks_index_t *ksi,
int n = 0;
for (int i = where; i < ksi->used && !hal_uuid_cmp(name, &ksi->names[ksi->index[i]].name); i++) {
+ if (n != ksi->names[ksi->index[i]].chunk)
+ return HAL_ERROR_IMPOSSIBLE;
if (blocknos != NULL && n < max_blocks)
blocknos[n] = ksi->index[i];
n++;
@@ -230,7 +232,7 @@ hal_error_t hal_ks_index_add(hal_ks_index_t *ksi,
return HAL_ERROR_BAD_ARGUMENTS;
if (ksi->used == ksi->size)
- return HAL_ERROR_NO_KEY_SLOTS_AVAILABLE;
+ return HAL_ERROR_NO_KEY_INDEX_SLOTS;
int where;
@@ -258,14 +260,6 @@ hal_error_t hal_ks_index_add(hal_ks_index_t *ksi,
return HAL_OK;
}
-/*
- * Should this be deleting the whole object instead of just one chunk?
- * Deferred for the moment as this is just an optimization. blockno
- * would need to become an array, adding complexity.
- *
- * See how we end up using it, I guess.
- */
-
hal_error_t hal_ks_index_delete(hal_ks_index_t *ksi,
const hal_uuid_t * const name,
const unsigned chunk,
@@ -301,6 +295,58 @@ hal_error_t hal_ks_index_delete(hal_ks_index_t *ksi,
return HAL_OK;
}
+hal_error_t hal_ks_index_delete_range(hal_ks_index_t *ksi,
+ const hal_uuid_t * const name,
+ const unsigned max_blocks,
+ unsigned *n_blocks,
+ unsigned *blocknos,
+ int *hint)
+{
+ if (ksi == NULL || ksi->index == NULL || ksi->names == NULL ||
+ ksi->size == 0 || ksi->used > ksi->size || name == NULL)
+ return HAL_ERROR_BAD_ARGUMENTS;
+
+ int where;
+
+ if (ksi->used == 0 || !ks_find(ksi, name, 0, hint, &where))
+ return HAL_ERROR_KEY_NOT_FOUND;
+
+ int n = 0;
+
+ for (int i = where; i < ksi->used && !hal_uuid_cmp(name, &ksi->names[ksi->index[i]].name); i++) {
+ if (n != ksi->names[ksi->index[i]].chunk)
+ return HAL_ERROR_IMPOSSIBLE;
+ if (blocknos != NULL && n < max_blocks)
+ blocknos[n] = ksi->index[i];
+ n++;
+ }
+
+ if (n_blocks != NULL)
+ *n_blocks = n;
+
+ /*
+ * Free the blocks and stuff them at the end of the free list.
+ */
+
+ if (blocknos != NULL) {
+ if (n > max_blocks)
+ return HAL_ERROR_RESULT_TOO_LONG;
+ const size_t len = (ksi->size - where - n) * sizeof(*ksi->index);
+ memmove(&ksi->index[where], &ksi->index[where + n], len);
+ ksi->used -= n;
+ for (int i = 0; i < n; i++) {
+ ksi->index[ksi->size - n + i] = blocknos[i];
+ memset(&ksi->names[blocknos[i]], 0, sizeof(ksi->names[blocknos[i]]));
+ }
+ where = -1;
+ }
+
+ if (hint != NULL)
+ *hint = where;
+
+ return HAL_OK;
+}
+
hal_error_t hal_ks_index_replace(hal_ks_index_t *ksi,
const hal_uuid_t * const name,
const unsigned chunk,
@@ -312,7 +358,7 @@ hal_error_t hal_ks_index_replace(hal_ks_index_t *ksi,
return HAL_ERROR_BAD_ARGUMENTS;
if (ksi->used == ksi->size)
- return HAL_ERROR_NO_KEY_SLOTS_AVAILABLE;
+ return HAL_ERROR_NO_KEY_INDEX_SLOTS;
int where;