Merge lp:~jelmer/brz/network-ftr into lp:brz

Proposed by Jelmer Vernooij
Status: Merged
Approved by: Jelmer Vernooij
Approved revision: 7926
Merged at revision: 7926
Proposed branch: lp:~jelmer/brz/network-ftr
Merge into: lp:brz
Diff against target: 155 lines (+87/-12)
3 files modified
breezy/bzr/versionedfile.py (+1/-12)
crates/bazaar-py/src/versionedfile.rs (+16/-0)
crates/bazaar/src/versionedfile.rs (+70/-0)
To merge this branch: bzr merge lp:~jelmer/brz/network-ftr
Reviewer Review Type Date Requested Status
Jelmer Vernooij Approve
Review via email: mp+459548@code.launchpad.net

Commit message

Migrate fulltext_network_to_record to rust

Description of the change

Migrate fulltext_network_to_record to rust

To post a comment you must log in.
Revision history for this message
Jelmer Vernooij (jelmer) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'breezy/bzr/versionedfile.py'
2--- breezy/bzr/versionedfile.py 2023-11-16 15:15:02 +0000
3+++ breezy/bzr/versionedfile.py 2024-01-27 22:59:16 +0000
4@@ -19,7 +19,6 @@
5 import functools
6 import itertools
7 import os
8-import struct
9 from copy import copy
10 from io import BytesIO
11 from typing import Any, Optional, Tuple
12@@ -49,6 +48,7 @@
13 ChunkedContentFactory = _versionedfile_rs.ChunkedContentFactory
14 AbsentContentFactory = _versionedfile_rs.AbsentContentFactory
15 record_to_fulltext_bytes = _versionedfile_rs.record_to_fulltext_bytes
16+fulltext_network_to_record = _versionedfile_rs.fulltext_network_to_record
17
18
19 adapter_registry = Registry[Tuple[str, str], Any, None]()
20@@ -2068,17 +2068,6 @@
21 yield from self._kind_factory[storage_kind](storage_kind, bytes, line_end)
22
23
24-def fulltext_network_to_record(kind, bytes, line_end):
25- """Convert a network fulltext record to record."""
26- (meta_len,) = struct.unpack("!L", bytes[line_end : line_end + 4])
27- record_meta = bytes[line_end + 4 : line_end + 4 + meta_len]
28- key, parents = bencode.bdecode_as_tuple(record_meta)
29- if parents == b"nil":
30- parents = None
31- fulltext = bytes[line_end + 4 + meta_len :]
32- return [FulltextContentFactory(key, parents, None, fulltext)]
33-
34-
35 def sort_groupcompress(parent_map):
36 """Sort and group the keys in parent_map into groupcompress order.
37
38
39=== modified file 'crates/bazaar-py/src/versionedfile.rs'
40--- crates/bazaar-py/src/versionedfile.rs 2024-01-27 13:51:13 +0000
41+++ crates/bazaar-py/src/versionedfile.rs 2024-01-27 22:59:16 +0000
42@@ -130,6 +130,21 @@
43 }
44 }
45
46+#[pyfunction]
47+fn fulltext_network_to_record(
48+ py: Python,
49+ _kind: &str,
50+ bytes: &[u8],
51+ line_end: usize,
52+) -> Vec<PyObject> {
53+ let record = bazaar::versionedfile::fulltext_network_to_record(bytes, line_end);
54+
55+ let sub = PyClassInitializer::from(AbstractContentFactory(Box::new(record)))
56+ .add_subclass(FulltextContentFactory);
57+
58+ vec![Py::new(py, sub).unwrap().to_object(py)]
59+}
60+
61 pub(crate) fn _versionedfile_rs(py: Python) -> PyResult<&PyModule> {
62 let m = PyModule::new(py, "versionedfile")?;
63 m.add_class::<AbstractContentFactory>()?;
64@@ -137,5 +152,6 @@
65 m.add_class::<ChunkedContentFactory>()?;
66 m.add_class::<AbsentContentFactory>()?;
67 m.add_function(wrap_pyfunction!(record_to_fulltext_bytes, m)?)?;
68+ m.add_function(wrap_pyfunction!(fulltext_network_to_record, m)?)?;
69 Ok(m)
70 }
71
72=== modified file 'crates/bazaar/src/versionedfile.rs'
73--- crates/bazaar/src/versionedfile.rs 2023-11-22 11:27:02 +0000
74+++ crates/bazaar/src/versionedfile.rs 2024-01-27 22:59:16 +0000
75@@ -3,6 +3,7 @@
76 use pyo3::types::{PyBytes, PyTuple};
77 use std::borrow::Cow;
78 use std::collections::HashMap;
79+use std::convert::TryInto;
80
81 #[derive(Debug)]
82 pub enum Error {
83@@ -716,3 +717,72 @@
84
85 length_bytes
86 }
87+
88+pub fn fulltext_network_to_record(bytes: &[u8], line_end: usize) -> FulltextContentFactory {
89+ // Extract meta_len from the network fulltext record
90+ let meta_len_bytes: [u8; 4] = bytes[line_end..line_end + 4]
91+ .try_into()
92+ .expect("Expected 4 bytes for meta_len");
93+ let meta_len = u32::from_be_bytes(meta_len_bytes) as usize;
94+
95+ // Extract record_meta using meta_len
96+ let record_meta = &bytes[line_end + 4..line_end + 4 + meta_len];
97+
98+ // Decode record_meta using Bencode
99+ let mut decoder = bendy::decoding::Decoder::new(record_meta);
100+
101+ let mut tuple = decoder
102+ .next_object()
103+ .expect("Failed to decode record_meta using Bencode")
104+ .expect("Failed to decode tuple using Bencode")
105+ .try_into_list()
106+ .unwrap();
107+
108+ fn decode_key(o: bendy::decoding::Object) -> Key {
109+ let mut ret = vec![];
110+
111+ let mut l = o.try_into_list().unwrap();
112+
113+ while let Some(b) = l.next_object().unwrap() {
114+ ret.push(b.try_into_bytes().unwrap().to_vec());
115+ }
116+
117+ Key::Fixed(ret)
118+ }
119+
120+ let key = decode_key(
121+ tuple
122+ .next_object()
123+ .expect("Failed to decode record_meta using Bencode")
124+ .expect("Failed to decode key using Bencode"),
125+ );
126+
127+ let parents = tuple
128+ .next_object()
129+ .expect("Failed to decode record_meta using Bencode")
130+ .expect("Failed to decode parents using Bencode");
131+
132+ // Convert parents from "nil" to None
133+ let parents = match parents {
134+ bendy::decoding::Object::Bytes(bytes) => {
135+ if bytes == b"nil" {
136+ None
137+ } else {
138+ panic!("Expected parents to be a list or nil");
139+ }
140+ }
141+ bendy::decoding::Object::List(mut l) => {
142+ let mut parents = vec![];
143+ while let Some(parent) = l.next_object().unwrap() {
144+ parents.push(decode_key(parent));
145+ }
146+ Some(parents)
147+ }
148+ _ => panic!("Expected parents to be a list or nil"),
149+ };
150+
151+ // Extract fulltext from the remaining bytes
152+ let fulltext = &bytes[line_end + 4 + meta_len..];
153+
154+ FulltextContentFactory::new(None, key, parents, fulltext.to_vec())
155+}

Subscribers

People subscribed via source and target branches