Advertisement
Guest User

halp

a guest
Apr 1st, 2020
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 2.51 KB | None | 0 0
  1. package main
  2.  
  3. import (
  4.     "fmt"
  5.     "sync"
  6. )
  7.  
  8. type SafeMap struct {
  9.     v   map[string]string
  10.     mux sync.Mutex
  11. }
  12.  
  13. // Inc increments the counter for the given key.
  14. func (c *SafeMap) Add(key, value string) {
  15.     c.mux.Lock()
  16.     // Lock so only one goroutine at a time can access the map c.v.
  17.     c.v[key] = value
  18.     c.mux.Unlock()
  19. }
  20.  
  21. // Value returns the current value of the counter for the given key.
  22. func (c *SafeMap) Value(key string) (res string,ok bool) {
  23.     c.mux.Lock()
  24.     // Lock so only one goroutine at a time can access the map c.v.
  25.     defer c.mux.Unlock()
  26.     res, ok = c.v[key]
  27.     return
  28. }
  29.  
  30.  
  31. type Fetcher interface {
  32.     // Fetch returns the body of URL and
  33.     // a slice of URLs found on that page.
  34.     Fetch(url string) (body string, urls []string, err error)
  35. }
  36.  
  37. var theMap = SafeMap{v: make(map[string]string)}
  38.  
  39. // Crawl uses fetcher to recursively crawl
  40. // pages starting with url, to a maximum of depth.
  41. func Crawl(url string, depth int, fetcher Fetcher) {
  42.    
  43.     // TODO: Fetch URLs in parallel.
  44.     // TODO: Don't fetch the same URL twice.
  45.     // This implementation doesn't do either:
  46.     _, ok := theMap.Value(url)
  47.    
  48.     if ok || depth == 0 {
  49.         return
  50.     }
  51.    
  52.     body, urls, err := fetcher.Fetch(url)
  53.     theMap.Add(url, body)
  54.    
  55.     if err != nil {
  56.         fmt.Println(err)
  57.         return
  58.     } else {
  59.         fmt.Printf("Found: url=%s : %s \n", url , body)
  60.     }
  61.    
  62.     for _,v := range urls {
  63.         go Crawl(v, depth -1 , fetcher)
  64.     }
  65. }
  66.  
  67. func main() {
  68.     Crawl("https://golang.org/", 4, fetcher)
  69. }
  70.  
  71. // fakeFetcher is Fetcher that returns canned results.
  72. type fakeFetcher map[string]*fakeResult
  73.  
  74. type fakeResult struct {
  75.     body string
  76.     urls []string
  77. }
  78.  
  79. func (f fakeFetcher) Fetch(url string) (string, []string, error) {
  80.     if res, ok := f[url]; ok {
  81.         return res.body, res.urls, nil
  82.     }
  83.     return "", nil, fmt.Errorf("Not found: %s", url)
  84. }
  85.  
  86. // fetcher is a populated fakeFetcher.
  87. var fetcher = fakeFetcher{
  88.     "https://golang.org/": &fakeResult{
  89.         "The Go Programming Language",
  90.         []string{
  91.             "https://golang.org/pkg/",
  92.             "https://golang.org/cmd/",
  93.         },
  94.     },
  95.     "https://golang.org/pkg/": &fakeResult{
  96.         "Packages",
  97.         []string{
  98.             "https://golang.org/",
  99.             "https://golang.org/cmd/",
  100.             "https://golang.org/pkg/fmt/",
  101.             "https://golang.org/pkg/os/",
  102.         },
  103.     },
  104.     "https://golang.org/pkg/fmt/": &fakeResult{
  105.         "Package fmt",
  106.         []string{
  107.             "https://golang.org/",
  108.             "https://golang.org/pkg/",
  109.         },
  110.     },
  111.     "https://golang.org/pkg/os/": &fakeResult{
  112.         "Package os",
  113.         []string{
  114.             "https://golang.org/",
  115.             "https://golang.org/pkg/",
  116.         },
  117.     },
  118. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement