How to resolve the algorithm Text processing/Max licenses in use step by step in the Go programming language

Published on 12 May 2024 09:40 PM
#Go

How to resolve the algorithm Text processing/Max licenses in use step by step in the Go programming language

Table of Contents

Problem Statement

A company currently pays a fixed sum for the use of a particular licensed software package.   In determining if it has a good deal it decides to calculate its maximum use of the software from its license management log file. Assume the software's licensing daemon faithfully records a checkout event when a copy of the software starts and a checkin event when the software finishes to its log file. An example of checkout and checkin events are:

Save the 10,000 line log file from   here   into a local file, then write a program to scan the file extracting both the maximum licenses that were out at any time, and the time(s) at which this occurs. Mirror of log file available as a zip here (offsite mirror).

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Text processing/Max licenses in use step by step in the Go programming language

This Go program analyzes data from a file named "mlijobs.txt" to find the maximum number of concurrent licenses used at any given time. A step-by-step explanation of the code:

  1. Constants:

    • filename: Sets the name of the file to be processed.
    • inoutField: Specifies the column index (1-based) in the file that indicates whether a job is an "IN" (license usage start) or "OUT" (license usage end).
    • timeField: Specifies the column index (1-based) in the file that contains the timestamp of the job.
    • numFields: Sets the expected number of columns in each line of the file.
  2. Main Function:

    • The main function is the entry point of the program.
  3. File Opening:

    • The program opens the file specified by filename for reading.
  4. Variables:

    • ml: Stores the maximum number of concurrent licenses used.
    • out: Keeps track of the current number of active licenses.
    • mlTimes: Stores the timestamps when the maximum number of licenses was used.
    • in: A byte slice representing the "IN" value.
  5. Scanner Initialization:

    • A bufio.Scanner is created to read the file line by line.
  6. Line-by-Line Processing:

    • The program uses a loop to process each line of the file.
    • For each line, it splits the line into fields using bytes.Fields.
    • It checks that the number of fields matches numFields. If not, it logs an error and terminates the program.
    • If the current field (specified by inoutField) is "IN," it decrements out and checks for negative license usage.
    • If the current field is not "IN," it increments out and compares it to ml.
    • If out is greater than ml, it updates ml and clears the mlTimes slice.
    • If out is equal to ml, it adds the timestamp to the mlTimes slice.
  7. Closing the File:

    • The defer statement ensures that the file is closed properly even if the program encounters an error.
  8. Printing Results:

    • After processing all lines, the program prints the maximum number of concurrent licenses (ml) and the corresponding timestamps (mlTimes).

Source code in the go programming language

package main

import (
    "bufio"
    "bytes"
    "fmt"
    "log"
    "os"
)

const (
    filename   = "mlijobs.txt"
    inoutField = 1
    timeField  = 3
    numFields  = 7
)

func main() {
    file, err := os.Open(filename)
    if err != nil {
        log.Fatal(err)
    }
    defer file.Close()
    var ml, out int
    var mlTimes []string
    in := []byte("IN")
    s := bufio.NewScanner(file)
    for s.Scan() {
        f := bytes.Fields(s.Bytes())
        if len(f) != numFields {
            log.Fatal("unexpected format,", len(f), "fields.")
        }
        if bytes.Equal(f[inoutField], in) {
            out--
            if out < 0 {
                log.Fatalf("negative license use at %s", f[timeField])
            }
            continue
        }
        out++
        if out < ml {
            continue
        }

        if out > ml {
            ml = out
            mlTimes = mlTimes[:0]
        }
        mlTimes = append(mlTimes, string(f[timeField]))
    }
    if err = s.Err(); err != nil {
        log.Fatal(err)
    }

    fmt.Println("max licenses:", ml)
    fmt.Println("at:")
    for _, t := range mlTimes {
        fmt.Println(" ", t)
    }
}


  

You may also check:How to resolve the algorithm Dining philosophers step by step in the Logtalk programming language
You may also check:How to resolve the algorithm Median filter step by step in the Phix programming language
You may also check:How to resolve the algorithm 100 doors step by step in the Klingphix programming language
You may also check:How to resolve the algorithm Strip whitespace from a string/Top and tail step by step in the TI-83 BASIC programming language
You may also check:How to resolve the algorithm Blum integer step by step in the Haskell programming language