Skip to content

Commit 1540abb

Browse files
authored
Add setTimes support (#116)
1 parent f46f73d commit 1540abb

File tree

8 files changed

+77
-2
lines changed

8 files changed

+77
-2
lines changed

python/python/hdfs_native/__init__.py

+6
Original file line numberDiff line numberDiff line change
@@ -107,3 +107,9 @@ def delete(self, path: str, recursive: bool) -> bool:
107107
is a non-empty directory, this will fail.
108108
"""
109109
return self.inner.delete(path, recursive)
110+
111+
def set_times(self, path: str, mtime: int, atime: int) -> None:
112+
"""
113+
Changes the modification time and access time of the file at `path` to `mtime` and `atime`, respectively.
114+
"""
115+
return self.inner.set_times(path, mtime, atime)

python/python/hdfs_native/_internal.pyi

+3-1
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,6 @@ class RawClient:
5353

5454
def rename(self, src: str, dst: str, overwrite: bool) -> None: ...
5555

56-
def delete(self, path: str, recursive: bool) -> bool: ...
56+
def delete(self, path: str, recursive: bool) -> bool: ...
57+
58+
def set_times(self, path: str, mtime: int, atime: int) -> None: ...

python/src/lib.rs

+4
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,10 @@ impl RawClient {
239239
pub fn delete(&self, path: &str, recursive: bool) -> PyHdfsResult<bool> {
240240
Ok(self.rt.block_on(self.inner.delete(path, recursive))?)
241241
}
242+
243+
pub fn set_times(&self, path: &str, mtime: u64, atime: u64) -> PyHdfsResult<()> {
244+
Ok(self.rt.block_on(self.inner.set_times(path, mtime, atime))?)
245+
}
242246
}
243247

244248
/// A Python module implemented in Rust.

python/tests/test_integration.py

+10-1
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,13 @@ def test_integration(minidfs: str):
5151
for i in range(0, 33 * 1024 * 1024):
5252
assert data.read(4) == i.to_bytes(4, 'big')
5353

54-
client.delete("/testfile", False)
54+
55+
mtime = 1717641455
56+
atime = 1717641456
57+
client.set_times("/testfile", mtime, atime)
58+
file_info = client.get_file_info("/testfile")
59+
assert file_info.modification_time == mtime
60+
assert file_info.access_time == atime
61+
62+
client.delete("/testfile", False)
63+

rust/minidfs/src/main/java/main/Main.java

+1
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ public static MiniDFSNNTopology generateTopology(Set<String> flags, Configuratio
211211
conf.set(DFSConfigKeys.DFS_NAMENODE_STATE_CONTEXT_ENABLED_KEY, "true");
212212
conf.set(DFSConfigKeys.DFS_HA_TAILEDITS_INPROGRESS_KEY, "true");
213213
conf.set(DFSConfigKeys.DFS_HA_TAILEDITS_PERIOD_KEY, "0ms");
214+
conf.set(DFSConfigKeys.DFS_NAMENODE_ACCESSTIME_PRECISION_KEY, "0");
214215
}
215216
return nnTopology;
216217
}

rust/src/client.rs

+9
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,15 @@ impl Client {
422422
.await
423423
.map(|r| r.result)
424424
}
425+
426+
/// Sets the modified and access times for a file. Times should be in milliseconds from the epoch.
427+
pub async fn set_times(&self, path: &str, mtime: u64, atime: u64) -> Result<()> {
428+
let (link, resolved_path) = self.mount_table.resolve(path);
429+
link.protocol
430+
.set_times(&resolved_path, mtime, atime)
431+
.await?;
432+
Ok(())
433+
}
425434
}
426435

427436
impl Default for Client {

rust/src/hdfs/protocol.rs

+23
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,29 @@ impl NamenodeProtocol {
388388
debug!("renewLease response: {:?}", &decoded);
389389
Ok(decoded)
390390
}
391+
392+
pub(crate) async fn set_times(
393+
&self,
394+
src: &str,
395+
mtime: u64,
396+
atime: u64,
397+
) -> Result<hdfs::SetTimesResponseProto> {
398+
let message = hdfs::SetTimesRequestProto {
399+
src: src.to_string(),
400+
mtime,
401+
atime,
402+
};
403+
debug!("setTimes request: {:?}", &message);
404+
405+
let response = self
406+
.proxy
407+
.call("setTimes", message.encode_length_delimited_to_vec())
408+
.await?;
409+
410+
let decoded = hdfs::SetTimesResponseProto::decode_length_delimited(response)?;
411+
debug!("setTimes response: {:?}", &decoded);
412+
Ok(decoded)
413+
}
391414
}
392415

393416
impl Drop for NamenodeProtocol {

rust/tests/test_integration.rs

+21
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ mod test {
187187
test_read_write(&client).await?;
188188
// We use writing to create files, so do this after
189189
test_recursive_listing(&client).await?;
190+
test_set_times(&client).await?;
190191

191192
Ok(())
192193
}
@@ -329,4 +330,24 @@ mod test {
329330

330331
Ok(())
331332
}
333+
334+
async fn test_set_times(client: &Client) -> Result<()> {
335+
client
336+
.create("/test", WriteOptions::default())
337+
.await?
338+
.close()
339+
.await?;
340+
341+
let mtime = 1717641455;
342+
let atime = 1717641456;
343+
344+
client.set_times("/test", mtime, atime).await?;
345+
346+
let file_info = client.get_file_info("/test").await?;
347+
348+
assert_eq!(file_info.modification_time, mtime);
349+
assert_eq!(file_info.access_time, atime);
350+
351+
Ok(())
352+
}
332353
}

0 commit comments

Comments
 (0)