Fix list_rels and list_nonrels in layeredRepository - return only visible objects

This commit is contained in:
anastasia
2021-08-23 15:10:10 +03:00
committed by lubennikovaav
parent b949127b06
commit e29bfa09b2
2 changed files with 37 additions and 52 deletions

View File

@@ -589,7 +589,7 @@ impl Timeline for LayeredTimeline {
let mut all_rels = HashSet::new();
let mut timeline = self;
loop {
let rels = timeline.layers.lock().unwrap().list_rels(spcnode, dbnode)?;
let rels = timeline.layers.lock().unwrap().list_rels(spcnode, dbnode, lsn)?;
all_rels.extend(rels.iter());
@@ -601,26 +601,6 @@ impl Timeline for LayeredTimeline {
}
}
// Now we have a list of all rels that appeared anywhere in the history. Filter
// out relations that were dropped.
//
// FIXME: We should pass the LSN argument to the calls above, and avoid scanning
// dropped relations in the first place.
let mut res: Result<()> = Ok(());
all_rels.retain(
|reltag| match self.get_rel_exists(RelishTag::Relation(*reltag), lsn) {
Ok(exists) => {
info!("retain: {} -> {}", *reltag, exists);
exists
}
Err(err) => {
res = Err(err);
false
}
},
);
res?;
Ok(all_rels)
}
@@ -643,24 +623,6 @@ impl Timeline for LayeredTimeline {
}
}
// Now we have a list of all nonrels that appeared anywhere in the history. Filter
// out dropped ones.
//
// FIXME: We should pass the LSN argument to the calls above, and avoid scanning
// dropped relations in the first place.
let mut res: Result<()> = Ok(());
all_rels.retain(|tag| match self.get_rel_exists(*tag, lsn) {
Ok(exists) => {
info!("retain: {} -> {}", *tag, exists);
exists
}
Err(err) => {
res = Err(err);
false
}
});
res?;
Ok(all_rels)
}

View File

@@ -204,34 +204,57 @@ impl LayerMap {
NUM_ONDISK_LAYERS.dec();
}
pub fn list_rels(&self, spcnode: u32, dbnode: u32) -> Result<HashSet<RelTag>> {
// List relations that exist at the lsn
pub fn list_rels(&self, spcnode: u32, dbnode: u32, lsn: Lsn) -> Result<HashSet<RelTag>> {
let mut rels: HashSet<RelTag> = HashSet::new();
for (seg, _entry) in self.segs.iter() {
for (seg, segentry) in self.segs.iter() {
if let RelishTag::Relation(reltag) = seg.rel {
// FIXME: skip if it was dropped before the requested LSN. But there is no
// LSN argument
if (spcnode == 0 || reltag.spcnode == spcnode)
&& (dbnode == 0 || reltag.dbnode == dbnode)
{
rels.insert(reltag);
// Add only if it exists at the requested LSN.
if let Some(open) = &segentry.open {
if open.get_end_lsn() > lsn {
rels.insert(reltag);
}
}
else if let Some((_k, _v)) = segentry
.historic
.range((Included(Lsn(0)), Included(lsn)))
.next_back()
{
rels.insert(reltag);
}
}
}
}
Ok(rels)
}
pub fn list_nonrels(&self, _lsn: Lsn) -> Result<HashSet<RelishTag>> {
// List non-relation relishes that exist at the lsn
pub fn list_nonrels(&self, lsn: Lsn) -> Result<HashSet<RelishTag>> {
let mut rels: HashSet<RelishTag> = HashSet::new();
// Scan the timeline directory to get all rels in this timeline.
for (seg, _entry) in self.segs.iter() {
// FIXME: skip if it was dropped before the requested LSN.
if let RelishTag::Relation(_) = seg.rel {
} else {
rels.insert(seg.rel);
for (seg, segentry) in self.segs.iter() {
if let RelishTag::Relation(_) = seg.rel { }
else
{
// Add only if it exists at the requested LSN.
if let Some(open) = &segentry.open {
if open.get_end_lsn() > lsn {
rels.insert(seg.rel);
}
}
else if let Some((_k, _v)) = segentry
.historic
.range((Included(Lsn(0)), Included(lsn)))
.next_back()
{
rels.insert(seg.rel);
}
}
}
Ok(rels)