Skip to content

Commit 5669253

Browse files
authored
feat: show index size in index info table (#222)
* feat: show index size in index info table Signed-off-by: Keming <kemingyang@tensorchord.ai> * fix clippy Signed-off-by: Keming <kemingyang@tensorchord.ai> * compute all the file for sealed segments Signed-off-by: Keming <kemingyang@tensorchord.ai> * fix dir_size Signed-off-by: Keming <kemingyang@tensorchord.ai> * display the sum size in the table Signed-off-by: Keming <kemingyang@tensorchord.ai> --------- Signed-off-by: Keming <kemingyang@tensorchord.ai>
1 parent e530742 commit 5669253

File tree

6 files changed

+74
-3
lines changed

6 files changed

+74
-3
lines changed

crates/service/src/index/mod.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,24 @@ pub struct IndexOptions {
6262
pub indexing: IndexingOptions,
6363
}
6464

65+
#[derive(Debug, Serialize, Deserialize)]
66+
#[serde(deny_unknown_fields)]
67+
pub struct SegmentSizeInfo {
68+
pub id: Uuid,
69+
#[serde(rename = "type")]
70+
pub typ: String,
71+
pub length: usize,
72+
pub size: u64,
73+
}
74+
6575
#[derive(Debug, Serialize, Deserialize)]
6676
pub struct IndexStat {
6777
pub indexing: bool,
6878
pub sealed: Vec<u32>,
6979
pub growing: Vec<u32>,
7080
pub write: u32,
7181
pub options: IndexOptions,
82+
pub sizes: Vec<SegmentSizeInfo>,
7283
}
7384

7485
pub struct Index<S: G> {
@@ -239,6 +250,12 @@ impl<S: G> Index<S> {
239250
growing: view.growing.values().map(|x| x.len()).collect(),
240251
write: view.write.as_ref().map(|(_, x)| x.len()).unwrap_or(0),
241252
options: self.options().clone(),
253+
sizes: view
254+
.sealed
255+
.values()
256+
.map(|x| x.size())
257+
.chain(view.growing.values().map(|x| x.size()))
258+
.collect(),
242259
}
243260
}
244261
}

crates/service/src/index/segments/growing.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use super::SegmentTracker;
44
use crate::index::IndexOptions;
55
use crate::index::IndexTracker;
6+
use crate::index::SegmentSizeInfo;
67
use crate::prelude::*;
78
use crate::utils::dir_ops::sync_dir;
89
use crate::utils::file_wal::FileWal;
@@ -140,6 +141,14 @@ impl<S: G> GrowingSegment<S> {
140141
pub fn len(&self) -> u32 {
141142
self.len.load(Ordering::Acquire) as u32
142143
}
144+
pub fn size(&self) -> SegmentSizeInfo {
145+
SegmentSizeInfo {
146+
id: self.uuid,
147+
typ: "growing".to_string(),
148+
length: self.len() as usize,
149+
size: (self.len() as u64) * (std::mem::size_of::<Log<S>>() as u64),
150+
}
151+
}
143152
pub fn vector(&self, i: u32) -> &[S::Scalar] {
144153
let i = i as usize;
145154
if i >= self.len.load(Ordering::Acquire) {

crates/service/src/index/segments/sealed.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use super::growing::GrowingSegment;
22
use super::SegmentTracker;
33
use crate::index::indexing::{DynamicIndexIter, DynamicIndexing};
4-
use crate::index::{IndexOptions, IndexTracker};
4+
use crate::index::{IndexOptions, IndexTracker, SegmentSizeInfo};
55
use crate::prelude::*;
6-
use crate::utils::dir_ops::sync_dir;
6+
use crate::utils::dir_ops::{dir_size, sync_dir};
77
use serde::{Deserialize, Serialize};
88
use std::path::PathBuf;
99
use std::sync::Arc;
@@ -58,6 +58,22 @@ impl<S: G> SealedSegment<S> {
5858
pub fn len(&self) -> u32 {
5959
self.indexing.len()
6060
}
61+
pub fn size(&self) -> SegmentSizeInfo {
62+
let mut info = SegmentSizeInfo {
63+
id: self.uuid,
64+
typ: "sealed".to_string(),
65+
length: self.len() as usize,
66+
size: 0,
67+
};
68+
let path = self._tracker.path.join("indexing");
69+
match dir_size(&path) {
70+
Ok(size) => info.size = size as u64,
71+
Err(e) => {
72+
panic!("Failed to get size of {:?}: {}", path, e);
73+
}
74+
}
75+
info
76+
}
6177
pub fn vector(&self, i: u32) -> &[S::Scalar] {
6278
self.indexing.vector(i)
6379
}

crates/service/src/utils/dir_ops.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,29 @@
1-
use std::fs::File;
1+
use std::fs::{read_dir, File};
2+
use std::io;
23
use std::path::Path;
34

45
pub fn sync_dir(path: impl AsRef<Path>) {
56
let file = File::open(path).expect("Failed to sync dir.");
67
file.sync_all().expect("Failed to sync dir.");
78
}
9+
10+
pub fn dir_size(dir: &Path) -> io::Result<usize> {
11+
let mut size = 0;
12+
if dir.is_dir() {
13+
for entry in read_dir(dir)? {
14+
let entry = entry?;
15+
let path = entry.path();
16+
let name = path.file_name().unwrap().to_string_lossy();
17+
if name.starts_with('.') {
18+
// ignore hidden files
19+
continue;
20+
}
21+
if path.is_dir() {
22+
size += dir_size(&path)?;
23+
} else {
24+
size += entry.metadata()?.len() as usize;
25+
}
26+
}
27+
}
28+
Ok(size)
29+
}

docs/indexing.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ We also provide a view `pg_vector_index_info` to monitor the progress of indexin
119119
| idx_sealed | int8[] | The number of tuples in each sealed segment. |
120120
| idx_growing | int8[] | The number of tuples in each growing segment. |
121121
| idx_write | int8 | The number of tuples in write buffer. |
122+
| idx_size | int8 | The byte size for all the segments. |
122123
| idx_config | text | The configuration of the index. |
123124

124125
## Examples

src/index/views.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ CREATE TYPE VectorIndexStat AS (
99
idx_sealed BIGINT[],
1010
idx_growing BIGINT[],
1111
idx_write BIGINT,
12+
idx_size BIGINT,
1213
idx_options TEXT
1314
);",
1415
name = "create_composites",
@@ -40,6 +41,11 @@ fn vector_stat(oid: pgrx::pg_sys::Oid) -> pgrx::composite_type!("VectorIndexStat
4041
})
4142
.unwrap();
4243
res.set_by_name("idx_write", stat.write as i64).unwrap();
44+
res.set_by_name(
45+
"idx_size",
46+
stat.sizes.iter().map(|x| x.size as i64).sum::<i64>(),
47+
)
48+
.unwrap();
4349
res.set_by_name("idx_options", serde_json::to_string(&stat.options))
4450
.unwrap();
4551
res

0 commit comments

Comments
 (0)