红黑树

进程调度简要总结

天大地大妈咪最大 提交于 2019-12-02 20:02:53
0. 权重 进程的优先级与内核的nice值对应,nice值降低对应权重增加; 内核根据进程类型和静态优先级计算权重值; 内核不仅维护进程自身的权重,还维护调度队列的权重,当进程被加入到调度队列时,也要该进程的权重增加到队列权重中; 1. 完全公平调度延时周期 内核可以通过参数sysctl_sched_latency配置一个时间间隔,用来保证每个可运行进程在此间隔下都能至少运行一次; 控制参数sched_nr_latency控制在上述时间间隔下最大的活动进程数目;如果活动进程的数目超过该配置数,则延时间隔时间成比例的进行扩展; sysctl_sched_latency = sysctl_sched_latency * nr_running / sched_nr_latency 进程分配到的时间根据进程权重在就绪队列中权重的比例进行分配; slice = slice * se->load / rq->load 2. 周期调度器扫描 周期调度器每个HZ扫描一次,更新当前进程的运行时间,并检查当前进程的运行时间是否超过了进程分配到的运行时间,如果超过了则标记进行重新调度标记; 在系统调用返回、中断返回等时机,会检查该标记,调用注册的实际调度方法的函数(比如公平调度注册的处理函数)处理进程,并进行实际的进程上下文切换; 3. 完全公平调度红黑树 完全公平调度就绪队列将进行维护在一棵红黑树中

Linux 内核红黑树分析

六月ゝ 毕业季﹏ 提交于 2019-12-02 12:15:13
内核版本为 linux4.2.1 本文主要从红黑树的代码实现入手,来讨论linux内核中是如何实现红黑树的(主要是插入和删除操作),其中涉及到的函数有三个__rb_insert __rb_erase_augmented ____rb_erase_color,本文将用图示的方式解析这三个函数。 1.红黑树性质 1.节点是红色或者黑色 2.根节点是黑色 3.所有叶子节点(null)都为黑色 4.红色节点的子节点都是黑色 5.从根节点到叶子节点所有路径上黑色节点数相同 2.基础 2.1 节点结构 struct rb_node { unsigned long __rb_parent_color; struct rb_node *rb_right; struct rb_node *rb_left; } __attribute__((aligned(sizeof(long)))); 不难看出 rb_left 和 rb_right 是该节点左右子节点的指针,结构体后面的__attribute__((aligned(sizeof(long))))让这个结构体按照4字节对齐(64位是8字节)。 __rb_parent_color这个参数名字有点奇怪,父亲的颜色?啥意思?不过当我们理解了这个参数的意义之后发现还真就应该叫这个名字。这个名字的意思其实是 “父亲和颜色”,它即代表了父节点的地址

算法基础(七)红黑树

亡梦爱人 提交于 2019-12-02 11:39:59
一、红黑树的特性 一个红黑树的节点node有如下5个属性: node(parent, left, right, color, key) 红黑树的5条特性,使其接近于一颗近似的“平衡”搜索树: 1、节点的颜色是红色或者黑色 2、根节点是黑色的 3、所有叶子节点是黑色的 4、一个红节点的两个子节点均为黑色 5、从树中任何一个节点到其所有后代叶节点的简单路径上,包含相同数目的黑色节点 二、算法伪代码 1、旋转 以X为支点的左旋操作LEFT-ROTATE(T,x),改变了x的右孩子、父节点,y的左孩子、父节点,以及y的左孩子的父节点,有可能改变父节点的左or右孩以及T.root,参照图示,比较容易写出左旋的伪代码。 LEFT-ROTATE(T,x) y = RIGHT(x) p = PARENT(x) RIGHT(x) = LEFT(y) if(LEFT(y) != T.nil) PARENT(LEFT(y)) = x PARENT(y) = p if(p == T.nil) T.root = y else if (x == LEFT(p)) LEFT(p) = y else RIGHT(p) = y LEFT(y) = x PARENT(x) = y 2、插入 RB-INSERT(T,z)将节点z插入到红黑树中。首先按照普通的二叉搜索树将节点z插入,并涂成红色。然后再调用一个辅助过程RB

pb_ds库 - 红黑树

这一生的挚爱 提交于 2019-12-02 11:09:22
#include <ext/pb_ds/tree_policy.hpp> #include <ext/pb_ds/assoc_container.hpp> using namespace __gnu_pbds; typedef tree<pt,null_type,less< pt >,rb_tree_tag,tree_order_statistics_node_update> rbtree; /* 定义一颗红黑树 int 关键字类型 null_type无映射(低版本g++为null_mapped_type) less<int>从小到大排序 rb_tree_tag 红黑树(splay_tree_tag) tree_order_statistics_node_update结点更新 插入t.insert(); 删除t.erase(); Rank:t.order_of_key(); 第K值:t.find_by_order(); 前驱:t.lower_bound(); 后继t.upper_bound(); a.join(b)b并入a 前提是两棵树的key的取值范围不相交 a.split(v,b)key小于等于v的元素属于a,其余的属于b T.lower_bound(x) >=x的min的迭代器 T.upper_bound((x) >x的min的迭代器 T.find_by_order(k)

深入理解HashMap和CurrentHashMap

懵懂的女人 提交于 2019-12-02 09:30:11
原文链接: https://segmentfault.com/a/1190000015726870 前言 Map 这样的 Key Value 在软件开发中是非常经典的结构,常用于在内存中存放数据。 本篇主要想讨论 ConcurrentHashMap 这样一个并发容器,在正式开始之前我觉得有必要谈谈 HashMap,没有它就不会有后面的 ConcurrentHashMap。 HashMap 众所周知 HashMap 底层是基于 数组 + 链表 组成的,不过在 jdk1.7 和 1.8 中具体实现稍有不同。 Base 1.7 1.7 中的数据结构图: 先来看看 1.7 中的实现。 这是 HashMap 中比较核心的几个成员变量;看看分别是什么意思? 初始化桶大小,因为底层是数组,所以这是数组默认的大小。 桶最大值。 默认的负载因子(0.75) table 真正存放数据的数组。 Map 存放数量的大小。 桶大小,可在初始化时显式指定。 负载因子,可在初始化时显式指定。 重点解释下负载因子: 由于给定的 HashMap 的容量大小是固定的,比如默认初始化: 1 public HashMap() { 2 this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR); 3 } 4 5 public HashMap(int initialCapacity

TreeMap源码实现类中文全解析

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-02 07:34:12
  TreeMap实现了SotredMap接口,它是有序的集合。而且是一个红黑树结构,每个key-value都作为一个红黑树的节点。如果在调用TreeMap的构造函数时没有指定比较器,则根据key执行自然排序,如果指定了比较器则按照比较器来进行排序。 一、数据结构   1、继承关系 public class TreeMap<K,V> extends AbstractMap<K,V> implements NavigableMap<K,V>, Cloneable, java.io.Serializable {}   2、实现接口 Serializable, Cloneable, Map<K,V>, NavigableMap<K,V>, SortedMap<K,V>   3、基本属性 private final Comparator<? super K> comparator; //比较器,是自然排序,还是定制排序 ,使用final修饰,表明一旦赋值便不允许改变 private transient Entry<K,V> root = null; //红黑树的根节点 private transient int size = 0; //TreeMap中存放的键值对的数量 private transient int modCount = 0; //修改的次数 二、源码解析  

java源码解析

跟風遠走 提交于 2019-12-02 06:41:52
String深入解析 String具有不变性的原因: String被final修饰,它不可能被继承,也就是任何对String的操作方法,都不会被继承覆写 String中保存数据的是一个char数组的value,它被final修饰,它的内存地址一旦赋值无法修改 public final class String implements java . io . Serializable , Comparable < String > , CharSequence { /** The value is used for character storage. */ private final char value [ ] ; } String相等判断源码 public boolean equals ( Object anObject ) { // 判断内存地址是否相同 if ( this == anObject ) { return true ; } // 待比较的对象是否是 String,如果不是 String,直接返回不相等 if ( anObject instanceof String ) { String anotherString = ( String ) anObject ; int n = value . length ; // 两个字符串的长度是否相等,不等则直接返回不相等

java源码解析

会有一股神秘感。 提交于 2019-12-02 06:39:43
String深入解析 String具有不变性的原因: String被final修饰,它不可能被继承,也就是任何对String的操作方法,都不会被继承覆写 String中保存数据的是一个char数组的value,它被final修饰,它的内存地址一旦赋值无法修改 public final class String implements java.io.Serializable, Comparable<String>, CharSequence { /** The value is used for character storage. */ private final char value[]; } String相等判断源码 public boolean equals(Object anObject) { // 判断内存地址是否相同 if (this == anObject) { return true; } // 待比较的对象是否是 String,如果不是 String,直接返回不相等 if (anObject instanceof String) { String anotherString = (String)anObject; int n = value.length; // 两个字符串的长度是否相等,不等则直接返回不相等 if (n == anotherString

Map随笔:最常用的Map——HashMap

╄→尐↘猪︶ㄣ 提交于 2019-12-02 05:59:58
目录 Map随笔:最常用的Map——HashMap 前言: 1,HashMap的一些属性(JDK8) 2,HashMap的构造函数(JDK8) 3,HashMap的一些方法(JDK8) Map随笔:最常用的Map——HashMap 前言: ​ HashMap作为我们工作中最常用的一个容器,去了解它的一些原理是非常有必要的,同时,HashMap也是面试中被问起的常客。所以接下来我就源码并穿插一些面试中最常被问起的面试题和大家分享一下HashMap相关的知识来避免以后在面试中再被HashMap相关知识所难住。 1,HashMap的一些属性(JDK8) 先看看源码中的几个常量属性 /** * 默认的数组容量 */ static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16 /** * 最大的数组容量 */ static final int MAXIMUM_CAPACITY = 1 << 30; /** * 默认加载因子值 */ static final float DEFAULT_LOAD_FACTOR = 0.75f; /** * java8优化了HashMap的数据结构,在链上的结构数据超过固定数量便会从链表转换成红黑树存储 * 链表转树的默认值 8 */ static final int TREEIFY

ConcurrentHashMap源码解析

青春壹個敷衍的年華 提交于 2019-12-02 05:38:57
首先看看CHM的重要成员变量: 1 public class ConcurrentHashMap<K,V> extends AbstractMap<K,V> 2 implements ConcurrentMap<K,V>, Serializable { 3 // table最大容量,为2的幂次方 4 private static final int MAXIMUM_CAPACITY = 1 << 30; 5 // 默认table初始容量大小 6 private static final int DEFAULT_CAPACITY = 16; 7 // 默认支持并发更新的线程数量 8 private static final int DEFAULT_CONCURRENCY_LEVEL = 16; 9 // table的负载因子 10 private static final float LOAD_FACTOR = 0.75f; 11 // 链表转换为红黑树的节点数阈值,超过这个值,链表转换为红黑树 12 static final int TREEIFY_THRESHOLD = 8; 13 // 在扩容期间,由红黑树转换为链表的阈值,小于这个值,resize期间红黑树就会转为链表 14 static final int UNTREEIFY_THRESHOLD = 6; 15 //