tuple: account the whole array in field.data and size
Before the patch a struct xrow_update_field object didn't account array header in its .size and .data members. Indeed, it was not needed, because anyway updates could be only 'flat'. For example, consider the tuple: [mp_array, mp_uint, mp_uint, mp_uint] ^ ^ pos1 pos2 Struct xrow_update_field.size and .data accounted memory from pos1 to pos2, without the array header. Number of fields was stored inside a rope object. This is why it made no sense to keep array header pointer. But now updates are going to be not flat, and not only for array. There will be an update tree. Each node of that tree will describe update of some part of a tuple. Some of the nodes will need to know exact borders of their children, including headers. It is going to be used for fast copying of neighbours of such children. Consider an example. Tuple with one field consisting of nested maps: tuple = {} tuple[1] = { a = { b = { c = { d = {1, 2, 3} } } } } Update: {{'+', '[1].a.b.c.d[1]', 1}, {'+', '[1].a.b.c.d[2]', 1}} To update such a tuple a simple tree will be built: root: [ [1] ] | isolated path: [ 'a.b.c' ] | leaves: [ [1] [2] [3] ] +1 +1 - Root node keeps the whole tuple borders. It is a rope with single field. This single field is a deeply updated map. Such deep multiple updates with long common prefixes are stored as an isolated path + map/array in the end. Here the isolated path is 'a.b.c'. It ends with the terminal array update. Assume, that operations are applied and it is time to save the result. Save starts from the root. Root rope will encode root array header, and will try to save the single field. The single field is an isolated update. It needs to save everything before old {1,2,3}, the new array {2,2,3}, and everything after the old array. The simplest way to do it - know exact borders of the old array {1,2,3} and memcpy all memory before and after. This is exactly what this patch allows to do. Everything before xrow_update_field.data, and after xrow_update_field.data + .size can be safely copied, and is not related to the field. To copy adjacent memory it is not even needed to know field type. Xrow_update_field.data and .size have the same meaning for all field types. Part of #1261
Loading
Please register or sign in to comment