diff -crbB ns-allinone-2.35/ns-2.35/queue/red.cc ns-2.35/queue/red.cc
*** ns-allinone-2.35/ns-2.35/queue/red.cc -- ::34.000000000 -
--- ns-2.35/queue/red.cc -- ::10.827778003 -
***************
*** , ****
edv_.count_bytes = ;
hdr_flags* hf = hdr_flags::access(pickPacketForECN(pkt));
if (edp_.setbit && hf->ect() &&
! (!edp_.use_mark_p || edv_.v_prob1 < edp_.mark_p)) {
hf->ce() = ; // mark Congestion Experienced bit
// Tell the queue monitor here - call emark(pkt)
return (); // no drop
--- , ----
edv_.count_bytes = ;
hdr_flags* hf = hdr_flags::access(pickPacketForECN(pkt));
if (edp_.setbit && hf->ect() &&
! (!edp_.use_mark_p || edv_.v_prob1 <= edp_.mark_p)) { // For DCTCP: '<' is changed to '<=' here
hf->ce() = ; // mark Congestion Experienced bit
// Tell the queue monitor here - call emark(pkt)
return (); // no drop
Only in ns-2.35/queue: red.cc~
diff -crbB ns-allinone-2.35/ns-2.35/tcl/lib/ns-default.tcl ns-2.35/tcl/lib/ns-default.tcl
*** ns-allinone-2.35/ns-2.35/tcl/lib/ns-default.tcl -- ::45.000000000 -
--- ns-2.35/tcl/lib/ns-default.tcl -- ::08.415778003 -
***************
*** , ****
--- , ---- Agent/TCP set SetCWRonRetransmit_ true ; # added on //.
# default changed on //.
+ # DCTCP
+ Agent/TCP set dctcp_ false;
+ Agent/TCP set dctcp_alpha_ 0.0;
+ Agent/TCP set dctcp_g_ 0.0625; # XXX Generate nam trace or plain old text trace for variables.
# When it's true, generate nam trace.
Only in ns-2.35/tcl/lib: ns-default.tcl~
Only in ns-2.35/tcp: .swp
diff -crbB ns-allinone-2.35/ns-2.35/tcp/tcp.cc ns-2.35/tcp/tcp.cc
*** ns-allinone-2.35/ns-2.35/tcp/tcp.cc -- ::46.000000000 -
--- ns-2.35/tcp/tcp.cc -- ::09.966778001 -
***************
*** , ****
--- , ----
bind("necnresponses_", &necnresponses_);
bind("ncwndcuts_", &ncwndcuts_);
bind("ncwndcuts1_", &ncwndcuts1_);
+ bind("dctcp_", &dctcp_);
+ bind("dctcp_alpha_", &dctcp_alpha_);
+ bind("dctcp_g_", &dctcp_g_);
#endif /* TCP_DELAY_BIND_ALL */ }
***************
*** , ****
--- , ----
delay_bind_init_one("overhead_");
delay_bind_init_one("tcpTick_");
delay_bind_init_one("ecn_");
+ // DCTCP
+ delay_bind_init_one("dctcp_");
+ delay_bind_init_one("dctcp_alpha_");
+ delay_bind_init_one("dctcp_g_");
+
delay_bind_init_one("SetCWRonRetransmit_");
delay_bind_init_one("old_ecn_");
delay_bind_init_one("bugfix_ss_");
***************
*** , ****
--- , ----
if (delay_bind(varName, localName, "overhead_", &overhead_, tracer)) return TCL_OK;
if (delay_bind(varName, localName, "tcpTick_", &tcp_tick_, tracer)) return TCL_OK;
if (delay_bind_bool(varName, localName, "ecn_", &ecn_, tracer)) return TCL_OK;
+ // Mohammad
+ if (delay_bind_bool(varName, localName, "dctcp_", &dctcp_, tracer)) return TCL_OK;
+ if (delay_bind(varName, localName, "dctcp_alpha_", &dctcp_alpha_ , tracer)) return TCL_OK;
+ if (delay_bind(varName, localName, "dctcp_g_", &dctcp_g_ , tracer)) return TCL_OK;
if (delay_bind_bool(varName, localName, "SetCWRonRetransmit_", &SetCWRonRetransmit_, tracer)) return TCL_OK;
if (delay_bind_bool(varName, localName, "old_ecn_", &old_ecn_ , tracer)) return TCL_OK;
if (delay_bind_bool(varName, localName, "bugfix_ss_", &bugfix_ss_ , tracer)) return TCL_OK;
***************
*** , ****
--- , ----
} else {
ssthresh_ = (int) decreasewin;
}
+ else if (how & CLOSE_SSTHRESH_DCTCP)
+ ssthresh_ = (int) (( - dctcp_alpha_/2.0) * windowd());
else if (how & THREE_QUARTER_SSTHRESH)
if (ssthresh_ < *cwnd_/)
ssthresh_ = (int)(*cwnd_/);
***************
*** , ****
--- , ----
if (first_decrease_ == || slowstart || decrease_num_ == 0.5) {
cwnd_ = halfwin;
} else cwnd_ = decreasewin;
+ else if (how & CLOSE_CWND_DCTCP)
+ cwnd_ = ( - dctcp_alpha_/2.0) * windowd();
else if (how & CWND_HALF_WITH_MIN) {
// We have not thought about how non-standard TCPs, with
// non-standard values of decrease_num_, should respond
***************
*** , ****
}
if (ssthresh_ < )
ssthresh_ = ;
! if (how & (CLOSE_CWND_HALF|CLOSE_CWND_RESTART|CLOSE_CWND_INIT|CLOSE_CWND_ONE))
cong_action_ = TRUE; fcnt_ = count_ = ;
--- , ----
}
if (ssthresh_ < )
ssthresh_ = ;
! if (cwnd_ < )
! cwnd_ = ;
! if (how & (CLOSE_CWND_HALF|CLOSE_CWND_RESTART|CLOSE_CWND_INIT|CLOSE_CWND_ONE|CLOSE_CWND_DCTCP))
cong_action_ = TRUE; fcnt_ = count_ = ;
***************
*** , ****
--- , ----
rtt_backoff();
else ecn_backoff_ = ;
} else ecn_backoff_ = ;
+ if (dctcp_)
+ slowdown(CLOSE_CWND_DCTCP|CLOSE_SSTHRESH_DCTCP);
+ else
slowdown(CLOSE_CWND_HALF|CLOSE_SSTHRESH_HALF);
++necnresponses_ ;
// added by sylvia to count number of ecn responses
Only in ns-2.35/tcp: tcp.cc~
diff -crbB ns-allinone-2.35/ns-2.35/tcp/tcp-full.cc ns-2.35/tcp/tcp-full.cc
*** ns-allinone-2.35/ns-2.35/tcp/tcp-full.cc -- ::54.000000000 -
--- ns-2.35/tcp/tcp-full.cc -- ::10.049778005 -
***************
*** , ****
--- , ----
/* Set ect() to 0. -M. Weigle 1/19/05 */
fh->ect() = ;
}
+
+ // For DCTCP, ect should be set on all packets
+ if (dctcp_)
+ fh->ect() = ect_;
+
if (ecn_ && ect_ && recent_ce_ ) {
// This is needed here for the ACK in a SYN, SYN/ACK, ACK
// sequence.
***************
*** , ****
// Q: how can this happen? if (maxseg_ == )
! maxseg_ = size_ - headersize();
else
size_ = maxseg_ + headersize(); int is_retransmit = (seqno < maxseq_);
int quiet = (highest_ack_ == maxseq_);
--- , ----
// Q: how can this happen? if (maxseg_ == )
! maxseg_ = size_; // Mohammad: changed from size_ - headersize();
! /* Mohammad: This else condition is unnecessary and conflates
! * with tcp.cc
else
size_ = maxseg_ + headersize();
+ */ int is_retransmit = (seqno < maxseq_);
int quiet = (highest_ack_ == maxseq_);
***************
*** , ****
--- , ----
*/
flags_ &= ~(TF_ACKNOW|TF_DELACK); + delack_timer_.force_cancel();
+
/*
* if we have reacted to congestion recently, the
* slowdown() procedure will have set cong_action_ and
***************
*** 1178,1183 ****
--- 1188,1195 ----
// and adjusted for SYNs and FINs which use up one number int highest = seqno + reliable;
+ if (highest > dctcp_maxseq)
+ dctcp_maxseq = highest;
if (highest > maxseq_) {
maxseq_ = highest;
//
***************
*** 1415,1421 ****
{
// we are now going to fast-retransmit and willtrace that event
trace_event("FAST_RETX");
-
recover_ = maxseq_; // recovery target
last_cwnd_action_ = CWND_ACTION_DUPACK;
return(foutput(seq, REASON_DUPACK)); // send one pkt
--- 1427,1432 ----
***************
*** 1564,1574 ****
--- 1576,1594 ----
* at time t0 = (0.0 + k * interval_) for some k such
* that t0 > now
*/
+ /*
+ * Mohammad: commented this out for more efficient
+ * delayed ack generation.
+ *
if (delack_interval_ > 0.0 &&
(delack_timer_.status() != TIMER_PENDING)) {
int last = int(now() / delack_interval_);
delack_timer_.resched(delack_interval_ * (last + 1.0) - now());
}
+ */
+
+ if (dctcp_)
+ update_dctcp_alpha(pkt); /*
* Try header prediction: in seq data or in seq pure ACK
***************
*** 1597,1602 ****
--- 1617,1641 ----
// if (ecn_) {
+ if (dctcp_) { // DCTCP
+ if (fh->ce() && fh->ect()) {
+ // no CWR from peer yet... arrange to
+ // keep sending ECNECHO
+ if (recent_ce_ == FALSE) {
+ ce_transition = 1;
+ recent_ce_ = TRUE;
+ } else {
+ ce_transition = 0;
+ }
+ } else if (datalen > 0 && !fh->ce() && fh->ect()){
+ if (recent_ce_ == TRUE) {
+ ce_transition = 1;
+ recent_ce_ = FALSE;
+ } else {
+ ce_transition = 0;
+ }
+ }
+ } else {
if (fh->ce() && fh->ect()) {
// no CWR from peer yet... arrange to
// keep sending ECNECHO
***************
*** 1607,1612 ****
--- 1646,1652 ----
recent_ce_ = FALSE;
}
}
+ } // Header predication basically looks to see
// if the incoming packet is an expected pure ACK
***************
*** 1638,1645 ****
--- 1678,1698 ----
// this routine scans all tcpcb's looking for
// DELACK segments and when it finds them
// changes DELACK to ACKNOW and calls tcp_output()
+
+ /* DCTCP receiver state machine */
+ if (dctcp_ && ce_transition && ((rcv_nxt_ - last_ack_sent_) > )) {
+ // Must send an immediate ACK with with previous ECN state
+ // before transitioning to new state
+ flags_ |= TF_ACKNOW;
+ recent_ce_ = !recent_ce_;
+ send_much(, REASON_NORMAL, maxburst_);
+ recent_ce_ = !recent_ce_;
+ }
+
rcv_nxt_ += datalen;
flags_ |= TF_DELACK;
+ // Mohammad
+ delack_timer_.resched(delack_interval_);
recvBytes(datalen); // notify application of "delivery"
//
// special code here to simulate the operation
***************
*** , ****
--- , ----
*/
if (datalen > ) {
flags_ |= TF_DELACK; // data there: wait
+ // Mohammad
+ delack_timer_.resched(delack_interval_);
} else {
flags_ |= TF_ACKNOW; // ACK peer's SYN
}
***************
*** , ****
// cong_action bit
//
if (ecn_) {
! if (fh->ce() && fh->ect())
recent_ce_ = TRUE;
! else if (fh->cwr())
recent_ce_ = FALSE;
} //
--- , ----
// cong_action bit
//
if (ecn_) {
! if (dctcp_) { // Mohammad
! if (fh->ce() && fh->ect()) {
! // no CWR from peer yet... arrange to
! // keep sending ECNECHO
! if (recent_ce_ == FALSE) {
! ce_transition = ;
recent_ce_ = TRUE;
! } else {
! ce_transition = ;
! }
! } else if (datalen > && !fh->ce() && fh->ect()){
! if (recent_ce_ == TRUE) {
! ce_transition = ;
recent_ce_ = FALSE;
+ } else {
+ ce_transition = ;
+ }
+ }
+ } else {
+ if (fh->ce() && fh->ect()) {
+ recent_ce_ = TRUE;
+ } else if (fh->cwr()) {
+ recent_ce_ = FALSE;
+ }
+ }
} //
***************
*** , ****
if ((!delay_growth_ || (rcv_nxt_ > )) &&
last_state_ == TCPS_ESTABLISHED) {
if (!partial || open_cwnd_on_pack_) {
! if (!ect_ || !hdr_flags::access(pkt)->ecnecho())
opencwnd();
}
} if ((state_ >= TCPS_FIN_WAIT_1) && (ackno == maxseq_)) {
ourfinisacked = TRUE;
}
--- , ----
if ((!delay_growth_ || (rcv_nxt_ > )) &&
last_state_ == TCPS_ESTABLISHED) {
if (!partial || open_cwnd_on_pack_) {
! if (!ect_ || !hdr_flags::access(pkt)->ecnecho() || ecn_burst_)
opencwnd();
}
} + // Mohammad: Detect bursts of ECN marks
+ if (ect_) {
+ if (!ecn_burst_ && hdr_flags::access(pkt)->ecnecho())
+ ecn_burst_ = TRUE;
+ else if (ecn_burst_ && ! hdr_flags::access(pkt)->ecnecho())
+ ecn_burst_ = FALSE;
+ }
+
if ((state_ >= TCPS_FIN_WAIT_1) && (ackno == maxseq_)) {
ourfinisacked = TRUE;
}
***************
*** , ****
--- , ----
// don't really have a process anyhow, just
// accept the data here as-is (i.e. don't
// require being in ESTABLISHED state)
+
+ /* Mohammad: For DCTCP state machine */
+ if (dctcp_ && ce_transition && ((rcv_nxt_ - last_ack_sent_) > )) {
+ // Must send an immediate ACK with with previous ECN state
+ // before transitioning to new state
+ flags_ |= TF_ACKNOW;
+ recent_ce_ = !recent_ce_;
+ send_much(, REASON_NORMAL, maxburst_);
+ recent_ce_ = !recent_ce_;
+ }
+
flags_ |= TF_DELACK;
+ // Mohammad
+ delack_timer_.resched(delack_interval_);
+
rcv_nxt_ += datalen;
tiflags = tcph->flags() & TH_FIN; ***************
*** , ****
--- , ----
// segments or hole-fills. Also,
// send an ACK (or SACK) to the other side right now.
// Note that we may have just a FIN here (datalen = 0)
+
+ /* Note: The DCTCP receiver conveys the ECN-CE
+ received on each out-of-order data packet */
+
int rcv_nxt_old_ = rcv_nxt_; // notify app. if changes
tiflags = reass(pkt);
if (rcv_nxt_ > rcv_nxt_old_) {
***************
*** , ****
--- , ----
}
reset_rtx_timer();
t_seqno_ = (highest_ack_ < ) ? iss_ : int(highest_ack_);
+ dctcp_alpha_update_seq = t_seqno_;
+ dctcp_maxseq = dctcp_alpha_update_seq;
fastrecov_ = FALSE;
dupacks_ = ;
}
+
+ /*
+ * Update dctcp alpha based on the ecn bit in the received packet.
+ * This procedure is called only when dctcp_ is 1.
+ */
+ void FullTcpAgent::update_dctcp_alpha(Packet *pkt)
+ {
+ int ecnbit = hdr_flags::access(pkt)->ecnecho();
+ int ackno = hdr_tcp::access(pkt)->ackno();
+ int acked_bytes = ackno - highest_ack_;
+
+ if (acked_bytes <= )
+ acked_bytes = size_;
+ dctcp_total += acked_bytes;
+ if (ecnbit) {
+ dctcp_marked += acked_bytes;
+ }
+
+ /* Check for barrier indicating its time to recalculate alpha.
+ * This code basically updated alpha roughly once per RTT.
+ */
+ if (ackno > dctcp_alpha_update_seq) {
+ double temp_alpha;
+ dctcp_alpha_update_seq = dctcp_maxseq;
+ if (dctcp_total > )
+ temp_alpha = ((double) dctcp_marked) / dctcp_total;
+ else
+ temp_alpha = 0.0;
+
+ dctcp_alpha_ = ( - dctcp_g_) * dctcp_alpha_ + dctcp_g_ * temp_alpha;
+ dctcp_marked = ;
+ dctcp_total = ;
+ }
+ }
+
+
/*
* deal with timers going off.
* 2 types for now:
***************
*** 2662,2668 ****
flags_ |= TF_ACKNOW;
send_much(1, REASON_NORMAL, 0);
}
! delack_timer_.resched(delack_interval_);
break;
default:
fprintf(stderr, "%f: FullTcpAgent(%s) Unknown Timeout type %d\n",
--- 2802,2809 ----
flags_ |= TF_ACKNOW;
send_much(1, REASON_NORMAL, 0);
}
! // Mohammad
! // delack_timer_.resched(delack_interval_);
break;
default:
fprintf(stderr, "%f: FullTcpAgent(%s) Unknown Timeout type %d\n",
***************
*** 2874,2879 ****
--- 3015,3023 ----
* packet. -M. Weigle 6/19/02
*/
last_cwnd_action_ = CWND_ACTION_DUPACK;
+ /* Mohammad: cut window by half when we have 3 dup ack */
+ if (dctcp_)
+ slowdown(CLOSE_SSTHRESH_HALF|CLOSE_CWND_HALF);
cancel_rtx_timer();
rtt_active_ = FALSE;
int amt = fast_retransmit(highest_ack_);
Only in ns-2.35/tcp: tcp-full.cc~
diff -crbB ns-allinone-2.35/ns-2.35/tcp/tcp-full.h ns-2.35/tcp/tcp-full.h
*** ns-allinone-2.35/ns-2.35/tcp/tcp-full.h -- ::52.000000000 -
--- ns-2.35/tcp/tcp-full.h -- ::10.052777998 -
***************
*** , ****
last_send_time_(-1.0), infinite_send_(FALSE), irs_(-),
delack_timer_(this), flags_(),
state_(TCPS_CLOSED), recent_ce_(FALSE),
! last_state_(TCPS_CLOSED), rq_(rcv_nxt_), last_ack_sent_(-) { } ~FullTcpAgent() { cancel_timers(); rq_.clear(); }
virtual void recv(Packet *pkt, Handler*);
--- , ----
last_send_time_(-1.0), infinite_send_(FALSE), irs_(-),
delack_timer_(this), flags_(),
state_(TCPS_CLOSED), recent_ce_(FALSE),
! last_state_(TCPS_CLOSED), rq_(rcv_nxt_), last_ack_sent_(-),
! dctcp_total(), dctcp_marked(), dctcp_alpha_update_seq(),
! dctcp_maxseq(), ce_transition() { } ~FullTcpAgent() { cancel_timers(); rq_.clear(); }
virtual void recv(Packet *pkt, Handler*);
***************
*** , ****
--- , ----
void finish();
void reset_rtx_timer(int); // adjust the rtx timer + void update_dctcp_alpha(Packet*); // DCTCP alpha update
+
virtual void timeout_action(); // what to do on rtx timeout
virtual void dupack_action(); // what to do on dup acks
virtual void pack_action(Packet*); // action on partial acks
***************
*** , ****
--- , ----
int last_state_; /* FSM state at last pkt recv */
int rcv_nxt_; /* next sequence number expected */
ReassemblyQueue rq_; /* TCP reassembly queue */
+
+ /*
+ * variables for DCTCP
+ */
+ int dctcp_total;
+ int dctcp_marked;
+ int dctcp_alpha_update_seq;
+ int dctcp_maxseq;
+ int ce_transition;
+
/*
* the following are part of a tcpcb in "real" RFC1323 TCP
*/
Only in ns-2.35/tcp: tcp-full.h~
diff -crbB ns-allinone-2.35/ns-2.35/tcp/tcp.h ns-2.35/tcp/tcp.h
*** ns-allinone-2.35/ns-2.35/tcp/tcp.h -- ::57.000000000 -
--- ns-2.35/tcp/tcp.h -- ::10.049778005 -
***************
*** , ****
#define CWND_HALF_WITH_MIN 0x00000200
#define TCP_IDLE 0x00000400
#define NO_OUTSTANDING_DATA 0x00000800
!
/*
* tcp_tick_:
* default 0.1,
--- 104,111 ----
#define CWND_HALF_WITH_MIN 0x00000200
#define TCP_IDLE 0x00000400
#define NO_OUTSTANDING_DATA 0x00000800
! #define CLOSE_SSTHRESH_DCTCP 0x00001000
! #define CLOSE_CWND_DCTCP 0x00002000
/*
* tcp_tick_:
* default 0.1,
***************
*** 432,437 ****
--- 433,444 ---- /* Used for ECN */
int ecn_; /* Explicit Congestion Notification */
+
+ /* Use for DCTCP */
+ int dctcp_;
+ double dctcp_alpha_;
+ double dctcp_g_;
+
int cong_action_; /* Congestion Action. True to indicate
that the sender responded to congestion. */
int ecn_burst_; /* True when the previous ACK packet
Only in ns-2.35/tcp: tcp.h~

dctcp-ns2-patch的更多相关文章

  1. dctcp-2.6.26-rev1.1.0.patch

    dctcp-2.6.26-rev1.1.0.patch diff -Naur linux-/include/linux/sysctl.h linux--dctcp-rev1.1.0/include/l ...

  2. 【NS2】NS2 教學手冊(转载)

    之前做毕设的时候搜索NS2的相关资料,发现这个里面涵盖很广,特此收藏,感谢原作者的辛勤劳作. NS2 教學手冊 ( NS2 Learning Guide) [快速連結區] My works  中文影音 ...

  3. 【NS2】cygwin+NS2.29安装之道 (转载)

    最近接了一个需要进行网络模拟的项目.对与网络模拟一窍不通的本人算是一个挑战.于是乎开始整日上网搜索相关的资料,没想到这个世界的资源真是丰富多彩.最后发现了一个网络模拟的流行软件NS2,在经过多次尝试后 ...

  4. [转]Patch文件结构详解

    N久不来 于是不知道扔在哪儿于是放这里先 如果你觉得碍事的话 帮我扔到合适的版块去.. 导读这是一篇说明文 它介绍了标准冒险岛更新文件(*.patch;*.exe)的格式文章的最后附了一段C#的参考代 ...

  5. 【腾讯Bugly干货分享】Android Patch 方案与持续交付

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57a31921ac3a1fb613dd40f3 Android 不仅系统版本众多 ...

  6. [译] 在Web API 2 中实现带JSON的Patch请求

    原文链接:The Patch Verb in Web API 2 with JSON 我想在.NET4.6 Web API 2 项目中使用Patch更新一个大对象中的某个字断,这才意识到我以前都没有用 ...

  7. Monkey Patch/Monkey Testing/Duck Typing/Duck Test

    Monkey Patch Monkey Testing Duck Typing Duck Test

  8. diff生成补丁与patch打补丁

    1.使用diff生成补丁: diff是Linux下的文件比较命令,参数这里就不说了,直接man一下就行了,不仅可以比较文件,也可以比较两个目录,并且可以将不同之处生成补丁文件,其实就是一种打补丁的命令 ...

  9. TeamViewer 12.0.71503 Patch By.Sound

    TeamViewer - the All-In-One Software for Remote Support and Online Meetings - Remote control any com ...

  10. iOS动态部署之RSA加密传输Patch补丁

    概要:这一篇博客主要说明下iOS客户端动态部署方案中,patch(补丁)是如何比较安全的加载到客户端中. 在整个过程中,需要使用RSA来加密(你可以选择其它的非对称加密算法),MD5来做校验(同样,你 ...

随机推荐

  1. python PIL库的使用

    )PIL可以做很多和图像处理相关的事情: 图像归档(Image Archives).PIL非常适合于图像归档以及图像的批处理任务.你可以使用PIL创建缩略图,转换图像格式,打印图像等等. 图像展示(I ...

  2. Zookeeper选举算法原理

    Zookeeper选举算法原理 Leader选举 Leader选举是保证分布式数据一致性的关键所在.当Zookeeper集群中的一台服务器出现以下两种情况之一时,需要进入Leader选举. (1) 服 ...

  3. new Map的妙用

    const actions = new Map([ [1, ['processing','IndexPage']], [2, ['fail','FailPage']], [3, ['fail','Fa ...

  4. 一些学习比较好的网站,及es6学习好网站,前端用的相关库,及知道的插件

    图形可视化:d3js  echarts https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects ...

  5. (转)使用LVS实现负载均衡原理及安装配置详解

    使用LVS实现负载均衡原理及安装配置详解 原文:https://www.cnblogs.com/liwei0526vip/p/6370103.html

  6. 修改Tomcat使用的JVM内存大小

    我的服务器的配置: # OS specific support.  $var _must_ be set to either true or false. JAVA_OPTS="-Xms10 ...

  7. volatile与synchronized实现原理

    参考文章:https://www.cnblogs.com/charlesblc/p/5994162.html --------------------------------------------- ...

  8. 转 Hibernate中cascade和inverse的作用

    Inverse和cascade是Hibernate映射中最难掌握的两个属性.两者都在对象的关联操作中发挥作用.1.明确inverse和cascade的作用inverse 决定是否把对对象中集合的改动反 ...

  9. [tools]转载汇总

    1. 发送请求工具—Advanced REST Client Advanced REST Client是Chrome浏览器下的一个插件,通过它可以发送http.https.WebSocket请求.

  10. 利用Map解决复杂业务

    遍历出题库表的题库名称和题库id,根据题目id即questionBankId获取 分组,即该题库题目总数,该题库题目正确数,该题库已回答题目数. <sqltemplate id="co ...