return gaps[offset];
}
-/*
- * mas_parent_gap() - Set the parent gap and any gaps above, as needed
- * @mas: The maple state
- * @offset: The gap offset in the parent to set
- * @new: The new gap value.
- *
- * Set the parent gap then continue to set the gap upwards, using the metadata
- * of the parent to see if it is necessary to check the node above.
- */
-static inline void mas_parent_gap(struct ma_state *mas, unsigned char offset,
- unsigned long new)
-{
- unsigned long meta_gap = 0;
- struct maple_node *pnode;
- struct maple_enode *penode;
- unsigned long *pgaps;
- unsigned char meta_offset;
- enum maple_type pmt;
-
- pnode = mte_parent(mas->node);
- pmt = mas_parent_type(mas, mas->node);
- penode = mt_mk_node(pnode, pmt);
- pgaps = ma_gaps(pnode, pmt);
-
-ascend:
- MAS_BUG_ON(mas, pmt != maple_arange_64);
- meta_offset = ma_meta_gap(pnode);
- meta_gap = pgaps[meta_offset];
-
- pgaps[offset] = new;
-
- if (meta_gap == new)
- return;
-
- if (offset != meta_offset) {
- if (meta_gap > new)
- return;
-
- ma_set_meta_gap(pnode, pmt, offset);
- } else if (new < meta_gap) {
- unsigned char i;
-
- /* Get the new maximum gap in the node */
- i = meta_offset = ma_meta_end(pnode, pmt);
- new = pgaps[i];
- while (i--) {
- if (pgaps[i] > new) {
- new = pgaps[i];
- meta_offset = i;
- }
- }
- ma_set_meta_gap(pnode, pmt, meta_offset);
- }
-
- if (ma_is_root(pnode))
- return;
-
- /* Go to the parent node. */
- pnode = mte_parent(penode);
- pmt = mas_parent_type(mas, penode);
- pgaps = ma_gaps(pnode, pmt);
- offset = mte_parent_slot(penode);
- penode = mt_mk_node(pnode, pmt);
- goto ascend;
-}
-
/*
* mas_update_gap() - Update a nodes gaps and propagate up if necessary.
* @mas: the maple state.
*/
static inline void mas_update_gap(struct ma_state *mas)
{
- unsigned char pslot;
- unsigned long p_gap;
- unsigned long max_gap;
+ unsigned char meta_offset, offset;
+ unsigned long *pgaps;
+ unsigned long max_gap, meta_gap;
+ struct maple_node *pnode;
+ struct maple_enode *penode;
+ enum maple_type pmt;
if (!mt_is_alloc(mas->tree))
return;
//printk("Updating gap for %p\n", mas->node);
max_gap = mas_max_gap(mas);
+ penode = mas->node;
+ do {
+ /* Ascend */
+ pnode = mte_parent(penode);
+ pmt = mas_parent_type(mas, penode);
+ offset = mte_parent_slot(penode);
+ pgaps = ma_gaps(pnode, pmt);
+
+ meta_offset = ma_meta_gap(pnode);
+ meta_gap = pgaps[meta_offset];
+ pgaps[offset] = max_gap;
+ if (meta_gap == max_gap)
+ return;
- pslot = mte_parent_slot(mas->node);
- p_gap = ma_gaps(mte_parent(mas->node),
- mas_parent_type(mas, mas->node))[pslot];
+ if (offset != meta_offset) {
+ if (meta_gap > max_gap)
+ return;
- if (p_gap != max_gap)
- mas_parent_gap(mas, pslot, max_gap);
+ ma_set_meta_gap(pnode, pmt, offset);
+ } else {
+ unsigned char i;
+
+ /* Get the new maximum gap in the node */
+ i = meta_offset = ma_meta_end(pnode, pmt);
+ max_gap = pgaps[i];
+ while (i--) {
+ if (pgaps[i] > max_gap) {
+ max_gap = pgaps[i];
+ meta_offset = i;
+ }
+ }
+ ma_set_meta_gap(pnode, pmt, meta_offset);
+ }
+ penode = mt_mk_node(pnode, pmt);
+ } while (!ma_is_root(pnode));
}
/*