aboutsummaryrefslogtreecommitdiff
path: root/src/api/k2v/index.rs
blob: 291464ab008e4789ec98a9c51bb6c5d64e1fd070 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
use std::sync::Arc;

use hyper::Response;
use serde::Serialize;

use garage_util::data::*;

use garage_table::util::*;

use garage_model::garage::Garage;
use garage_model::k2v::item_table::{BYTES, CONFLICTS, ENTRIES, VALUES};

use crate::helpers::*;
use crate::k2v::api_server::ResBody;
use crate::k2v::error::*;
use crate::k2v::range::read_range;

pub async fn handle_read_index(
	garage: Arc<Garage>,
	bucket_id: Uuid,
	prefix: Option<String>,
	start: Option<String>,
	end: Option<String>,
	limit: Option<u64>,
	reverse: Option<bool>,
) -> Result<Response<ResBody>, Error> {
	let reverse = reverse.unwrap_or(false);

	let node_id_vec = garage
		.system
		.cluster_layout()
		.all_nongateway_nodes()
		.to_vec();

	let (partition_keys, more, next_start) = read_range(
		&garage.k2v.counter_table.table,
		&bucket_id,
		&prefix,
		&start,
		&end,
		limit,
		Some((DeletedFilter::NotDeleted, node_id_vec)),
		EnumerationOrder::from_reverse(reverse),
	)
	.await?;

	let s_entries = ENTRIES.to_string();
	let s_conflicts = CONFLICTS.to_string();
	let s_values = VALUES.to_string();
	let s_bytes = BYTES.to_string();

	let resp = ReadIndexResponse {
		prefix,
		start,
		end,
		limit,
		reverse,
		partition_keys: partition_keys
			.into_iter()
			.map(|part| {
				let vals = part.filtered_values(&garage.system.cluster_layout());
				ReadIndexResponseEntry {
					pk: part.sk,
					entries: *vals.get(&s_entries).unwrap_or(&0),
					conflicts: *vals.get(&s_conflicts).unwrap_or(&0),
					values: *vals.get(&s_values).unwrap_or(&0),
					bytes: *vals.get(&s_bytes).unwrap_or(&0),
				}
			})
			.collect::<Vec<_>>(),
		more,
		next_start,
	};

	json_ok_response::<Error, _>(&resp)
}

#[derive(Serialize)]
struct ReadIndexResponse {
	prefix: Option<String>,
	start: Option<String>,
	end: Option<String>,
	limit: Option<u64>,
	reverse: bool,

	#[serde(rename = "partitionKeys")]
	partition_keys: Vec<ReadIndexResponseEntry>,

	more: bool,
	#[serde(rename = "nextStart")]
	next_start: Option<String>,
}

#[derive(Serialize)]
struct ReadIndexResponseEntry {
	pk: String,
	entries: i64,
	conflicts: i64,
	values: i64,
	bytes: i64,
}