1. 程式人生 > >爬蟲中的基於LRU演算法的URL過濾器

爬蟲中的基於LRU演算法的URL過濾器

public class LRUFilter {
 private int CurrentCacheSize;
 private int MAX;
 private int MAXIP;
 private HashMap<Integer,HashMap> rootMap;
 private HashMap<Integer,Int> DBMap;
 private Connection con;
 private LinkedList<Element> lQueue;
 private HashMap<Integer,Element> slQueue;
 public LRUFilter(Connection c){
  this(20000,10000,c);
 }
 public LRUFilter(int capable,int oneip,Connection c){
  MAX=capable;
  CurrentCacheSize=0;
  MAXIP=oneip;
  rootMap=new HashMap<Integer,HashMap>();
  DBMap=new HashMap<Integer,Int>();
  lQueue=new LinkedList<Element>();
  slQueue=new HashMap<Integer,Element>();
  con=c;
  initialCache();
 }
 private boolean hit(HashMap<Integer,DBElement> urlMap,int ip,int url){
  boolean contain=false;
  slQueue.get(ip).hits++;
  DBElement dbe=null;
  if((dbe=urlMap.get(url))!=null){
   contain=true;
   if(dbe.flag==0){
    dbe.hits++;
    dbe.flag=1;
   }else
    dbe.hits++;
  }else{
   if(DBMap.get(ip).value<MAXIP){
    contain=false;
    urlMap.put(url, new DBElement(1,ip,2));
    CurrentCacheSize++;
    while(CurrentCacheSize>MAX)
     toDB(0);
    if(urlMap.size()>MAXIP){
     toDB(ip);
     fromDB(ip);
    }
   }else{
    contain=toDBDirect(url,new DBElement(1,ip,0));
    Int i=null;
    if(!contain&&(i=DBMap.get(ip))!=null)
     i.value+=1;
   }
  }
  return contain;
 }
 private boolean notHit(int ip,int url){
  return hit(fromDB(ip),ip,url);
 }
 /*
  * get the keyip and its count into the DBMap which are the count cache of the ip
  */
 private void initialCache(){
  try{
   String sql="use crawler;select keyip,count(keyip) from visited group by keyip";
   Statement stm=con.createStatement();
   ResultSet rs=stm.executeQuery(sql);
   while(rs.next())
    DBMap.put(rs.getInt(1), new Int(rs.getInt(2)));
   rs.close();
   stm.close();
  }catch(Exception e){
   e.printStackTrace();
  }
 }
 /*
  * filter the url, ip is the url's ip.
  */
 public boolean contain(String ip,String url){
  HashMap<Integer,DBElement> urlMap=null;
  int keyip=ip.hashCode();
  int keyurl=url.hashCode();
  if((urlMap=rootMap.get(keyip))!=null)
   return hit(urlMap,keyip,keyurl);
  else
   return notHit(keyip,keyurl);
 }
 /*
  * If ip is equal to 0,get the least recently use ip from the lQueue,writ all
  *  the url belong the ip to the database, change the number of url belong this ip in DBMap
  *  if ip is not equal to 0, write the url belong this ip to the database.renew the lQueue and slQueue and DBMap
  */
 private boolean toDB(int ip){
  HashMap<Integer,DBElement> urlMap=null;
  Int count=null;
  int num;
  if(ip==0){
   Collections.sort(lQueue,new MyComparator());
   Element e=null;
   if((e=lQueue.poll())!=null){
    ip=e.ip;
    slQueue.remove(ip);
    if((urlMap=rootMap.remove(ip))!=null){
     num=writeToDB(urlMap);
     if((count=DBMap.get(ip))!=null)
      count.value+=num;
     CurrentCacheSize-=urlMap.size();
    }
   }else
    return false;//empty
  }else{
   if((urlMap=rootMap.remove(ip))!=null){
    num=writeToDB(urlMap);
    if((count=DBMap.get(ip))!=null)
     count.value+=num;
    CurrentCacheSize-=urlMap.size();
   }
   lQueue.remove(slQueue.remove(ip));
  }
  return true;
 }
 private HashMap<Integer,DBElement>  fromDB(int ip){
  Int i=null;
  HashMap<Integer,DBElement> urlMap=null;
  if((i=DBMap.get(ip))!=null){
   if(i.value>MAXIP)
    urlMap=readFromDB(ip,true);
   else
    urlMap=readFromDB(ip,false); 
  }else{
   urlMap=new HashMap<Integer,DBElement>();
   DBMap.put(ip, new Int(0));
  }
  while(urlMap.size()+CurrentCacheSize>MAX)
   toDB(0);
 
  for(int j=0;j<lQueue.size();j++)
   lQueue.get(j).hits=0;
  Element e=new Element(ip,0);
  lQueue.add(e);
  slQueue.put(ip, e);
  rootMap.put(ip, urlMap);
  CurrentCacheSize+=urlMap.size();
  while(CurrentCacheSize>MAX)
   toDB(0);
  return urlMap;
 }
 /*
  * write to database,return the number of
  * record which is inserted into the database
  */
 private int writeToDB(HashMap<Integer,DBElement> urlDBMap){
  boolean insertAble=false,updateAble=false;
  int num=0;
  try{
   PreparedStatement insertStm=con.prepareStatement("use crawler;insert into visited values(?,?,?);");
   DBElement dbe=null;
   for(Iterator i=urlDBMap.entrySet().iterator();i.hasNext();){
    Entry<Integer,DBElement> entry=(Entry<Integer,DBElement>)i.next();
    int keyurl=entry.getKey();
    DBElement e=entry.getValue();
    if(e.flag==2){
     insertStm.setInt(1, keyurl);
     insertStm.setInt(2,e.hits);
     insertStm.setInt(3, e.keyip);
     insertStm.addBatch();
     num++;
     insertAble=true;
    }
   }
   if(insertAble)
    insertStm.executeBatch();
   insertStm.close();
   PreparedStatement updateStm=con.prepareStatement("use crawler;update visited set hits=? where keyurl=?;");
   for(Iterator i=urlDBMap.entrySet().iterator();i.hasNext();){
    Entry<Integer,DBElement> entry=(Entry<Integer,DBElement>)i.next();
    int keyurl=entry.getKey();
    DBElement e=entry.getValue();
    if(e.flag==1){
     updateStm.setInt(1, e.hits);
     updateStm.setInt(2, keyurl);
     updateStm.addBatch();
     updateAble=true;
    }
   }
   if(updateAble)
    updateStm.executeBatch();
   updateStm.close();
   con.commit();
  }catch(Exception e){
   e.printStackTrace();
  }
  return num;
 }
 /*
  * read from database,if the number of the record
  * which belong to the ip exceed the MAXIP,just read
  * half of it from the database
  */
 public HashMap<Integer,DBElement> readFromDB(int ip,boolean exceed){
  HashMap<Integer,DBElement> urlMap=new HashMap<Integer,DBElement>();
  String sql=null;
  int count=MAXIP/2;
  if(exceed)
   sql="select top "+count+" keyurl,hits from visited where keyip=?;";
  else
   sql="select keyurl,hits from visited where keyip=?;";
  try{
   PreparedStatement stm=con.prepareStatement(sql);
   stm.setInt(1, ip);
   ResultSet rs=stm.executeQuery();
   while(rs.next())
    urlMap.put(rs.getInt(1),new DBElement(rs.getInt(2)));
   rs.close();
   stm.close();
  }catch(Exception e){
   e.printStackTrace();
  }
  return urlMap;
 }
 /*
  * insert into the database directly
  */
 private boolean toDBDirect(int keyurl,DBElement dbe){
  boolean contain=false;
  try{
   Statement stm=con.createStatement();
   String sql=null;
   ResultSet rs=stm.executeQuery("use crawler;select hits from visited where keyurl="+keyurl+";");
  
   if(rs.next()){
    contain=true;
    int hits=rs.getInt(1)+dbe.hits;
    sql="use crawler;update visited set hits="+hits+" where keyurl="+keyurl+";";
   }else{
    contain=false;
    sql="use crawler;insert into visited values("+keyurl+","+dbe.hits+","+dbe.keyip+");";
   
   }
   stm.executeUpdate(sql);
   rs.close();
   stm.close();
  }catch(Exception e){
   e.printStackTrace();
  }
  return contain;
 }
 /*
  * store the cache data
  */
 public void store(){
  while(toDB(0));
 }
 /*
  * tool classes
  */
 private class Element{
  public Element(int i,int h){ip=i;hits=h;}
  public int ip;
  public int hits;
 }
 private class Int{
  public Int(int v){value=v;}
  public int value=0;
 }
 private class DBElement{
  public DBElement(int h,int k,int f){hits=h;keyip=k;flag=f;}
  public DBElement(int h){hits=h;}
  public int hits=0;
  public int keyip=0;
  /*
   * 0 stand for not change
   * 1 stand for change
   * 2 stand for a new record
   */
  public int flag=0;;
 }
 private class MyComparator implements Comparator{
  public int compare(Object o1,Object o2){
   Element e1=(Element)o1;
   Element e2=(Element)o2;
   if(e1.hits<e1.hits)
    return -1;
   else if(e1.hits>e2.hits)
    return 1;
   else
    return 0;
  }
 }
}

相關推薦

爬蟲基於LRU演算法URL過濾器

public class LRUFilter { private int CurrentCacheSize; private int MAX; private int MAXIP; private HashMap<Integer,HashMap> rootMap; private HashMap&

淺談網路爬蟲深度優先演算法和簡單程式碼實現

學過網站設計的小夥伴們都知道網站通常都是分層進行設計的,最上層的是頂級域名,之後是子域名,子域名下又有子域名等等,同時,每個子域名可能還會擁有多個同級域名,而且URL之間可能還有相互連結,千姿百態,由此構成一個複雜的網路。 當一個網站的URL非常多的時候,我們務必要設計好URL,否則在後期的理解

淺談網路爬蟲廣度優先演算法和程式碼實現

前幾天給大家分享了網路爬蟲中深度優先演算法的介紹及其程式碼實現過程,沒來得及上車的小夥伴們可以戳這篇文章——淺談網路爬蟲中深度優先演算法和簡單程式碼實現。今天小編給大家分享網路爬蟲中廣度優先演算法的介紹及其程式碼實現過程。 廣度優先演算法和深度優先演算法恰好相反,這裡繼續以上圖的二叉樹為例。

基於LRU演算法的快取池——阿里筆試題

這是一題2011年阿里實習生招聘的筆試題,感覺不錯,拿來給大家分享一下,原題如下: 在進入我的淘寶頁面時,此頁面需要獲取登入的使用者的相關資訊,在訪問量少的情況下,可以採用直接訪問資料庫的方式,但當訪問量太高時,會導致資料庫壓力過高,因此通常採取的方法為將使用者資訊進行快取

opencv3.3基於ssd演算法的目標檢測示例教程

環境:Ubuntu16.04 / opencv3.3 #以下命令在終端執行 環境準備: 1:安裝依賴項: sudo apt-get install build-essential sudo apt-get install cmake git libgtk2.0-dev pk

項目一:第十二天 1、常見權限控制方式 2、基於shiro提供url攔截方式驗證權限 3、在realm授權 5、總結驗證權限方式(四種) 6、用戶註銷7、基於treegrid實現菜單展示

eal 重復數 規則 認證通過 delete get 數據庫 filter 登陸 1 課程計劃 1、 常見權限控制方式 2、 基於shiro提供url攔截方式驗證權限 3、 在realm中授權 4、 基於shiro提供註解方式驗證權限 5、 總結驗證權限方式(四種) 6、

基於FPGA的快速值濾波演算法--轉載我之前的blog的內容

轉: http://xiongwei.site/ 在實時影象採集中,不可避免的會引入噪聲,尤其是干擾噪聲和椒鹽噪聲,噪聲的存在嚴重影響邊緣檢測的效果,中值濾波是一種基於排序統計理論的非線性平滑計數,能有效平滑噪聲,且能有效保護影象的邊緣資訊,所以被廣泛用於數字影象

網遊伺服器的GUID(唯一標識碼)實現-基於snowflake演算法

嚴以律己,寬以待人. 三思而後行. GMail/GTalk: yanglinbo#google.com; MSN/Email: tx7do#yahoo.com.cn; QQ: 3 0 3 3 9 6 9 2 0 .

Crawler/ML:爬蟲技術(基於urllib.request庫從網頁獲取圖片)+HierarchicalClustering層次聚類演算法,實現自動從網頁獲取圖片然後根據圖片色調自動分類

網上教程太囉嗦,本人最討厭一大堆沒用的廢話,直接上,就是幹! 網路爬蟲?非監督學習? 只有兩步,只有兩個步驟? Are you kidding me? Are you ok? 來吧,follow me, come on! 一、爬蟲下載圖片 第一步:首先,我們從網

基於快閃記憶體資料庫的CCF-LRU演算法優化

2018.5.28 今天查看了關於flashdb中關於快取演算法的資料結構,發現了3dsim的資料結構是不一樣的,然後又去看了一遍3Dsim的資料結構,發現flashdb的資料結構實際是可以優化的。下面對這個點簡單的分析下。 首先來看下flashdb的資料結構

Python 網路爬蟲 009 (程式設計) 通過正則表示式來獲取一個網頁的所有的URL連結,並下載這些URL連結的原始碼

通過 正則表示式 來獲取一個網頁中的所有的 URL連結,並下載這些 URL連結 的原始碼 使用的系統:Windows 10 64位 Python 語言版本:Python 2.7.10 V 使用的程式設計 Python 的整合開發環境:PyCharm 201

python爬蟲對含中文的url處理

在練習urllib操作中,遇到了url中含有中文字元的問題。比如http://dotamax.com/,看下原始碼的話,上方的搜尋框的name=p,輸入內容點選搜尋以後,通過GET方法進行傳遞,比如我們搜尋”意“,url變為http://dotamax.com/search

動手實現 LRU 演算法,以及 Caffeine 和 Redis 的快取淘汰策略

> 我是風箏,公眾號「古時的風箏」。 文章會收錄在 [JavaNewBee](https://github.com/huzhicheng/JavaNewBee) 中,更有 Java 後端知識圖譜,從小白到大牛要走的路都在裡面。 那天我在 LeetCode 上刷到一道 LRU 快取機制的問題,第 146 題

Android基於Socket的網絡通信

ram pre 請求 android 鏈接 ted block param gen Socket鏈接的建立過程: 1.服務器監聽 2.客戶端發出請求 3.建立鏈接 4.通信 Socketl特點: 1.Socket基於TCP鏈接,數據傳輸有保障 2.Socket適用於建立長時

MySQL基於mysqldump和二進制日誌log-bin二進制日誌進行邏輯備份以及基於時間點的還原

總結 mysql-bin lin .sql bin -h eat log-bin 之前 本文出處:http://www.cnblogs.com/wy123/p/6956464.html 本文僅模擬使用mysqldump和log-bin二進制日誌進行簡單

Java基於HTTP協議網絡編程

copy 統一 throws 網絡編程 設置 查詢 trac enc pac java中為我們的網絡支持提供了java.net包,能夠使我們以編程的方式來訪問Web服務功能,這篇博客,就跟大家分享一下。Java中的網絡編程的知識。主要是學習下該java.net包下的

爬蟲——爬蟲使用正則表達式

txt文件 點擊 頁碼 range safari 頁面 gen odin ace 下面我們嘗試爬取內涵段子網站:http://www.neihan8.com/article/list_5_1.html 打開之後,當你進行翻頁的時候,不能註意到,url地址的變化:

centos7基於hadoop安裝hive(CentOS7+hadoop2.8.0+hive2.1.1)

root drive notepad lds opts 裝配 -- 3.2 window 1下載hive 下載地址:http://hive.apache.org/downloads.html 點擊上圖的Download release now! 如圖:

爬蟲代理的設置問題介紹

ade tar 相對 sts macintosh 代理 per ons decode 下面我們來梳理一下這些庫的代理的設置方法。 1.獲取代理 在做測試之前,我們需要先獲取一個可用代理,搜索引擎搜索“代理”關鍵字,就可以看到有許多代理服務

Spark HA 配置spark.deploy.zookeeper.url 的意思

pts ubun 後來 spark 錯誤 解密 mas java 說明 Spark HA的配置網上很多,最近我在看王林的Spark的視頻,要付費的。那個人牛B吹得很大,本事應該是有的,但是有本事,不一定就是好老師。一開始吹中國第一,吹著吹著就變成世界第一。就算你真的是世界第