SSH:利用Struts2+Hibernate4+Spring4+SQLServer框架,搭建一個前後端web網站(3)
阿新 • • 發佈:2019-01-03
為你推薦(模仿cache排程演算法)
- 網站有為你推薦模組,我是模仿計算機組成原理中的cache的排程演算法。簡單介紹:網站通過將所有的資訊和標籤掛鉤。我給每個使用者20條的“儲存標籤”的空間。其中10條為被標記成old的標籤,10條為被標記成new標籤(這樣的目的是既採用了使用者最進做多瀏覽偏好,又結合了使用者歷史瀏覽偏好)。其中的標籤存貯方式如下:
假設使用者瀏覽一條資訊後有如下標籤和次數和標籤關係(其中標籤有被標記成new和old2個選項,代表這個標籤式最近儲存還是之前儲存)
歷史— 1次 —- new
科技 — 2次 —- new
C — 2次 —- new
……
U —-10——old(第20條)
10條被標記成new的標籤,也就是說最開始的時候前10條標籤設定為new,如果有新的插入(11條了),就將被標記成new中訪問次數最少的標籤降級為old(標記成old), 將新標籤標記成new,次數0,插入資料庫。
如果到了有10條被標記成new,10條被標記成old的標籤,又有一個新標籤插入,就將被標記成old的標籤中訪問次數最少的刪除,將被標記成new的標籤中訪問次數最少的降級,將新的重新插入
如果一條標籤已經被儲存到資料庫中了,再次被訪問,那麼標籤被訪問量count +1,同時如過這條被標記成old,將這條資料標記稱new,找出被標記成new的標籤中被訪問次數最少的,降級成old(標記成old)
//進行使用者cache儲存
void saveCacheTag(String tagId){
//tagId 每一篇文章的id 如 3/4/12
String []tempTagId = tagId.split("/");
String name = (String)ServletActionContext.getRequest().getSession().getAttribute("name");
if(name == null) return;
User user = userService.getUserByName (name);
//得到原有的這個作者的cacheTag
List<CacheTag> cacheTagList = cacheTagService.getUserCacheTagList(user.getId());
/*new 5條 old 5條
* 會有這樣的情況:1.new沒有滿 old也必定沒有滿 直接插入 2.new滿了 old沒滿 需要將一條new 變成old 再插入資料
* 3.new滿了old也滿了 將一條old資訊 去掉(即update)成新的這條
* 計數相加原則:如果已經存在這條資訊 1.再new中 --->count加一 2.在old中--->flag變成new count不加一 檢視是不是需要去掉old降級一個new等等
*/
//是否已經存在map<tagid,new/old>
Map<Integer, CacheTag> mapNew = new HashMap<Integer, CacheTag>();
Map<Integer, CacheTag> mapOld = new HashMap<Integer, CacheTag>();
for(CacheTag var : cacheTagList) {
if(var.getFlag().equals("new")) {
mapNew.put(var.getTagId(), var);
}else {
mapOld.put(var.getTagId(), var);
}
}
for(int i = 0; i < tempTagId.length; i++) {
Integer tag_id = Integer.parseInt(tempTagId[i]);
if(mapNew.containsKey(tag_id)) {
CacheTag tempCacheTag = mapNew.get(tag_id);
tempCacheTag.setCount(tempCacheTag.getCount() + 1);
cacheTagService.save(tempCacheTag);
}else if(mapOld.containsKey(Integer.parseInt(tempTagId[i]))) {
//有這條記錄 不過是old 需要變成new
CacheTag tempCacheTag = mapOld.get(tag_id);
tempCacheTag.setFlag("new");
if(mapNew.size() < 5){ //直接從old 變成 new(條數max-5)
mapNew.put(tag_id, tempCacheTag);
mapOld.remove(tag_id);
cacheTagService.save(tempCacheTag);
} else {//需要從new中找到一條降級為old
int count = Integer.MAX_VALUE;
CacheTag minCacheTag = new CacheTag();
for(Integer var : mapNew.keySet()) {
if(mapNew.get(var).getCount() <= count) {
minCacheTag = mapNew.get(var); //需腰降級的new
}
}
if(mapOld.size() < 5){ //將直接降級bian old
minCacheTag.setFlag("old");
cacheTagService.save(minCacheTag);//儲存降級的new
cacheTagService.save(tempCacheTag);//儲存升級的old
mapOld.put(minCacheTag.getTagId(), minCacheTag);
mapNew.remove(minCacheTag.getId());
mapNew.put(tag_id, tempCacheTag);
mapOld.remove(tag_id);
}else {
//升級的old和降級的new互相換就可以(old 滿了)
mapNew.remove(minCacheTag.getTagId());
mapOld.remove(tag_id);//移除升級的old 的ID
minCacheTag.setFlag("old");
cacheTagService.save(minCacheTag);//儲存降級的new
cacheTagService.save(tempCacheTag);//儲存升級的old
mapOld.put(minCacheTag.getTagId(), minCacheTag);
mapNew.put(tag_id, tempCacheTag);
}
}
}else {
//如果之前不存在這個tag
//new 是否滿了
if(mapNew.size() < 5) {
CacheTag tempCacheTag = new CacheTag(tag_id, user.getId(), 0, "new");
mapNew.put(tag_id, tempCacheTag);
cacheTagService.save(tempCacheTag);
}else {
//將new中的一個轉變成old
//找到點選量最小的new變成old
int count = Integer.MAX_VALUE;
CacheTag minCacheTag = new CacheTag();
for(Integer var : mapNew.keySet()) {
if(mapNew.get(var).getCount() <= count) {
minCacheTag = mapNew.get(var);//需要降級的new
}
}
if((mapOld.size()) < 5){
//儲存新的這個new 如果old 沒滿
CacheTag tempCacheTag = new CacheTag(tag_id, user.getId(), 0, "new");
mapNew.put(tag_id, tempCacheTag);
mapNew.remove(minCacheTag.getTagId());
mapOld.put(minCacheTag.getTagId(), minCacheTag);
minCacheTag.setFlag("old");
cacheTagService.save(minCacheTag);//儲存降級的new
cacheTagService.save(tempCacheTag);//儲存新的new
}else {
//找到需要去掉的這個old (內容替換成 新的這個new)
count = Integer.MAX_VALUE;
CacheTag minCacheTag2 = new CacheTag();
for(Integer var : mapOld.keySet()) {
if(mapOld.get(var).getCount() <= count) {
minCacheTag2 = mapOld.get(var);//找到需要淘汰的old
}
}
mapOld.remove(minCacheTag2.getTagId());
minCacheTag2.setFlag("new");
minCacheTag2.setCount(0);
minCacheTag2.setTagId(tag_id);
cacheTagService.save(minCacheTag2);//儲存新的這個new
minCacheTag.setFlag("old");
cacheTagService.save(minCacheTag);//需要降級的new
mapNew.remove(minCacheTag.getTagId());
mapNew.put(tag_id, minCacheTag2);
mapOld.put(minCacheTag.getTagId(), minCacheTag);
}
}
}
}
}