storage.go 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. package main
  2. import (
  3. "bufio"
  4. "fmt"
  5. "log"
  6. "os"
  7. "strings"
  8. "sync"
  9. )
  10. const (
  11. format = "%s<>%s\n"
  12. )
  13. var links sync.Map
  14. func readLinks(path string) {
  15. file, err := os.OpenFile(path, os.O_CREATE|os.O_RDONLY, 0644)
  16. if err != nil {
  17. log.Fatalf("Failed to open %s!\n", path)
  18. }
  19. defer func() {
  20. if err := file.Close(); err != nil {
  21. log.Fatalf("Failed to close file: %s", err)
  22. }
  23. }()
  24. scanner := bufio.NewScanner(file)
  25. for scanner.Scan() {
  26. line := scanner.Text()
  27. if line == "" {
  28. break
  29. }
  30. parts := strings.Split(line, "<>")
  31. if len(parts) != 2 {
  32. log.Fatalf("Wrong line format: %s", line)
  33. }
  34. links.Store(parts[0], parts[1])
  35. }
  36. if err := scanner.Err(); err != nil {
  37. log.Fatalf("Scanner error: %s", err)
  38. }
  39. }
  40. func addLink(link string, toSave chan<- string) string {
  41. linkID := getHash(link)
  42. existingLink, loaded := links.LoadOrStore(linkID, link)
  43. if loaded {
  44. if existingLink != link {
  45. log.Printf("Have collision:\n%s\n%s\n", link, existingLink)
  46. }
  47. } else {
  48. toSave <- fmt.Sprintf(format, linkID, link)
  49. }
  50. return linkID
  51. }
  52. func getLink(linkID string) string {
  53. link, found := links.Load(linkID)
  54. if !found {
  55. return ""
  56. }
  57. return link.(string)
  58. }
  59. func saveLink(path string, toSave <-chan string) {
  60. file, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
  61. if err != nil {
  62. log.Fatal(err)
  63. }
  64. defer func() {
  65. if err := file.Close(); err != nil {
  66. log.Fatalf("Failed to close file: %s", err)
  67. }
  68. }()
  69. for item := range toSave {
  70. if _, err := file.WriteString(item); err != nil {
  71. log.Fatal(err)
  72. }
  73. }
  74. }