Show More
@@ -59,12 +59,22 b' py_class!(pub class MixedIndex |py| {' | |||||
59 |
|
59 | |||
60 | /// Return Revision if found, raises a bare `error.RevlogError` |
|
60 | /// Return Revision if found, raises a bare `error.RevlogError` | |
61 | /// in case of ambiguity, same as C version does |
|
61 | /// in case of ambiguity, same as C version does | |
62 | def get_rev(&self, node: PyBytes) -> PyResult<Option<Revision>> { |
|
62 | def get_rev(&self, pynode: PyBytes) -> PyResult<Option<Revision>> { | |
63 | let opt = self.get_nodetree(py)?.borrow(); |
|
63 | let opt = self.get_nodetree(py)?.borrow(); | |
64 | let nt = opt.as_ref().unwrap(); |
|
64 | let nt = opt.as_ref().unwrap(); | |
65 | let idx = &*self.cindex(py).borrow(); |
|
65 | let idx = &*self.cindex(py).borrow(); | |
66 | let node = node_from_py_bytes(py, &node)?; |
|
66 | let node = node_from_py_bytes(py, &pynode)?; | |
67 |
nt.find_bin(idx, node.into()) |
|
67 | match nt.find_bin(idx, node.into()) | |
|
68 | { | |||
|
69 | Ok(None) => | |||
|
70 | // fallback to C implementation, remove once | |||
|
71 | // https://bz.mercurial-scm.org/show_bug.cgi?id=6554 | |||
|
72 | // is fixed (a simple backout should do) | |||
|
73 | self.call_cindex(py, "get_rev", &PyTuple::new(py, &[pynode.into_object()]), None)? | |||
|
74 | .extract(py), | |||
|
75 | Ok(Some(rev)) => Ok(Some(rev)), | |||
|
76 | Err(e) => Err(nodemap_error(py, e)), | |||
|
77 | } | |||
68 | } |
|
78 | } | |
69 |
|
79 | |||
70 | /// same as `get_rev()` but raises a bare `error.RevlogError` if node |
|
80 | /// same as `get_rev()` but raises a bare `error.RevlogError` if node | |
@@ -94,27 +104,34 b' py_class!(pub class MixedIndex |py| {' | |||||
94 | } |
|
104 | } | |
95 | } |
|
105 | } | |
96 |
|
106 | |||
97 | def partialmatch(&self, node: PyObject) -> PyResult<Option<PyBytes>> { |
|
107 | def partialmatch(&self, pynode: PyObject) -> PyResult<Option<PyBytes>> { | |
98 | let opt = self.get_nodetree(py)?.borrow(); |
|
108 | let opt = self.get_nodetree(py)?.borrow(); | |
99 | let nt = opt.as_ref().unwrap(); |
|
109 | let nt = opt.as_ref().unwrap(); | |
100 | let idx = &*self.cindex(py).borrow(); |
|
110 | let idx = &*self.cindex(py).borrow(); | |
101 |
|
111 | |||
102 | let node_as_string = if cfg!(feature = "python3-sys") { |
|
112 | let node_as_string = if cfg!(feature = "python3-sys") { | |
103 | node.cast_as::<PyString>(py)?.to_string(py)?.to_string() |
|
113 | pynode.cast_as::<PyString>(py)?.to_string(py)?.to_string() | |
104 | } |
|
114 | } | |
105 | else { |
|
115 | else { | |
106 | let node = node.extract::<PyBytes>(py)?; |
|
116 | let node = pynode.extract::<PyBytes>(py)?; | |
107 | String::from_utf8_lossy(node.data(py)).to_string() |
|
117 | String::from_utf8_lossy(node.data(py)).to_string() | |
108 | }; |
|
118 | }; | |
109 |
|
119 | |||
110 | let prefix = NodePrefix::from_hex(&node_as_string).map_err(|_| PyErr::new::<ValueError, _>(py, "Invalid node or prefix"))?; |
|
120 | let prefix = NodePrefix::from_hex(&node_as_string).map_err(|_| PyErr::new::<ValueError, _>(py, "Invalid node or prefix"))?; | |
111 |
|
121 | |||
112 | nt.find_bin(idx, prefix) |
|
122 | match nt.find_bin(idx, prefix) { | |
113 | // TODO make an inner API returning the node directly |
|
123 | Ok(None) => | |
114 | .map(|opt| opt.map( |
|
124 | // fallback to C implementation, remove once | |
115 | |rev| PyBytes::new(py, idx.node(rev).unwrap().as_bytes()))) |
|
125 | // https://bz.mercurial-scm.org/show_bug.cgi?id=6554 | |
116 | .map_err(|e| nodemap_error(py, e)) |
|
126 | // is fixed (a simple backout should do) | |
117 |
|
127 | self.call_cindex( | ||
|
128 | py, "partialmatch", | |||
|
129 | &PyTuple::new(py, &[pynode]), None | |||
|
130 | )?.extract(py), | |||
|
131 | Ok(Some(rev)) => | |||
|
132 | Ok(Some(PyBytes::new(py, idx.node(rev).unwrap().as_bytes()))), | |||
|
133 | Err(e) => Err(nodemap_error(py, e)), | |||
|
134 | } | |||
118 | } |
|
135 | } | |
119 |
|
136 | |||
120 | /// append an index entry |
|
137 | /// append an index entry |
@@ -428,6 +428,46 b" mercurial don't crash" | |||||
428 | data-length: 121088 |
|
428 | data-length: 121088 | |
429 | data-unused: 0 |
|
429 | data-unused: 0 | |
430 | data-unused: 0.000% |
|
430 | data-unused: 0.000% | |
|
431 | ||||
|
432 | Sub-case: fallback for corrupted data file | |||
|
433 | ------------------------------------------ | |||
|
434 | ||||
|
435 | Sabotaging the data file so that nodemap resolutions fail, triggering fallback to | |||
|
436 | (non-persistent) C implementation. | |||
|
437 | ||||
|
438 | ||||
|
439 | $ UUID=`hg debugnodemap --metadata| grep 'uid:' | \ | |||
|
440 | > sed 's/uid: //'` | |||
|
441 | $ FILE=.hg/store/00changelog-"${UUID}".nd | |||
|
442 | $ python -c "fobj = open('$FILE', 'r+b'); fobj.write(b'\xff' * 121088); fobj.close()" | |||
|
443 | ||||
|
444 | The nodemap data file is still considered in sync with the docket. This | |||
|
445 | would fail without the fallback to the (non-persistent) C implementation: | |||
|
446 | ||||
|
447 | $ hg log -r b355ef8adce0949b8bdf6afc72ca853740d65944 -T '{rev}\n' --traceback | |||
|
448 | 5002 | |||
|
449 | ||||
|
450 | The nodemap data file hasn't been fixed, more tests can be inserted: | |||
|
451 | ||||
|
452 | $ hg debugnodemap --dump-disk | f --bytes=256 --hexdump --size | |||
|
453 | size=121088 | |||
|
454 | 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| | |||
|
455 | 0010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| | |||
|
456 | 0020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| | |||
|
457 | 0030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| | |||
|
458 | 0040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| | |||
|
459 | 0050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| | |||
|
460 | 0060: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| | |||
|
461 | 0070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| | |||
|
462 | 0080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| | |||
|
463 | 0090: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| | |||
|
464 | 00a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| | |||
|
465 | 00b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| | |||
|
466 | 00c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| | |||
|
467 | 00d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| | |||
|
468 | 00e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| | |||
|
469 | 00f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| | |||
|
470 | ||||
431 | $ mv ../tmp-data-file $FILE |
|
471 | $ mv ../tmp-data-file $FILE | |
432 | $ mv ../tmp-docket .hg/store/00changelog.n |
|
472 | $ mv ../tmp-docket .hg/store/00changelog.n | |
433 |
|
473 |
General Comments 0
You need to be logged in to leave comments.
Login now