Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
lezhnev74 committed Sep 3, 2024
0 parents commit c9743f5
Show file tree
Hide file tree
Showing 98 changed files with 21,353 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.idea
local
dev_notes
_local
35 changes: 35 additions & 0 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Publish Docker image

on:
push:
tags:
- '*'

jobs:
push_to_registry:
name: Push Docker image to Docker Hub
runs-on: ubuntu-latest
steps:
- name: Check out the repo
uses: actions/checkout@v4

- name: Log in to Docker Hub
uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
with:
images: lezhnev74/heaplog

- name: Build and push Docker image
uses: docker/build-push-action@3b5e8027fcad23fda98b2e3ac259d8d67585f671
with:
context: .
file: ./Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
28 changes: 28 additions & 0 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# This workflow will build a golang project
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go

name: Go

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

jobs:

build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.22'

- name: Build
run: go build -v ./...

- name: Test
run: go test -p 2 -v ./...
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
_local
.idea
dev
11 changes: 11 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FROM golang:1.22-bookworm AS build
WORKDIR /app
COPY . ./
RUN go build -o /app/binary

FROM debian:bookworm-slim
RUN apt-get update
RUN apt-get install ugrep
COPY --from=build /app/binary /heaplog
EXPOSE 8393
ENTRYPOINT ["/heaplog"]
83 changes: 83 additions & 0 deletions common/location.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package common

import (
"log"
"slices"
)

// Location addresses an area of bytes [From,To)
type Location struct {
From, To uint64
}

func (s Location) Intersects(s2 Location) bool {
return s.From <= s2.To && s.To >= s2.From
}

// Split slices a segment into many
func (s Location) Split(maxLen uint64) (ret []Location) {

for {
if uint64(s.Len()) <= maxLen {
ret = append(ret, s)
return
}

ret = append(ret, Location{s.From, s.From + maxLen})
s = Location{s.From + maxLen, s.To}
}
}

func (s Location) Len() int64 { return int64(s.To - s.From) }

func (s Location) Contains(i uint64) bool { return i >= s.From && i < s.To }

func (s Location) Remove(s2 Location) (ret []Location) {

// valid locations
if s.Len() < 0 || s2.Len() < 0 {
log.Panicf("Invalid ranges: %v or %v", s, s2)
}

intersection := Location{max(s.From, s2.From), min(s.To, s2.To)}

// If the intersection is empty, then the difference is the union of the two ranges.
if intersection.Len() < 0 {
return []Location{s}
}

// Otherwise, the difference is the two ranges minus the intersection.
result := Location{From: s.From, To: intersection.From}
if result.Len() > 0 {
ret = append(ret, result)
}
result = Location{From: intersection.To, To: s.To}
if result.Len() > 0 {
ret = append(ret, result)
}
return
}

func MergeLocations(src []Location) (ret []Location) {
slices.SortFunc(src, func(a, b Location) int { return int(a.From - b.From) })

if len(src) < 2 {
return src
}

cur := src[0]

for i := 1; i < len(src); i++ {
if src[i].Intersects(cur) {
cur = Location{min(cur.From, src[i].From), max(cur.To, src[i].To)}
continue
}

ret = append(ret, cur)
cur = src[i]
}

ret = append(ret, cur)

return
}
74 changes: 74 additions & 0 deletions common/util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package common

import (
"fmt"
"golang.org/x/xerrors"
"hash/crc32"
"os"
"time"
)

var (
crc32t = crc32.MakeTable(0xD5828281)
)

// HashString is a quick and idempotent hashing
func HashString(s string) string {
h := crc32.Checksum([]byte(s), crc32t)
return fmt.Sprintf("%d", h)
}

func SliceToAny[T any](in []T) (ret []any) {
ret = make([]any, len(in))
for i, v := range in {
ret[i] = v
}
return
}

func GroupSlice[T any](in []T, groupBy func(T) string) (groups [][]T) {
var (
curGroup []T
lastGroup string
)
for i, t := range in {
if i == 0 {
curGroup = append(curGroup, t)
lastGroup = groupBy(t)
continue
}

g := groupBy(t)
if lastGroup == g {
curGroup = append(curGroup, t)
continue
}

groups = append(groups, curGroup)
curGroup = []T{t}
lastGroup = g
}

if len(curGroup) != 0 {
groups = append(groups, curGroup)
}

return
}

func MakeTime(format, value string) time.Time {
t, err := time.ParseInLocation(format, value, time.UTC)
if err != nil {
panic(err)
}
return t
}

func FileSize(path string) (uint64, error) {
fi, err := os.Stat(path)
if err != nil {
err = xerrors.Errorf("all files: %w", err)
return 0, err
}
return uint64(fi.Size()), nil
}
67 changes: 67 additions & 0 deletions common/util_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package common

import (
"fmt"
"github.com/stretchr/testify/require"
"strconv"
"testing"
)

func TestGroupSlice(t *testing.T) {
type test struct {
in []string
g func(string) string
expected [][]string
}

var empty [][]string
tests := []test{
{
in: []string{},
g: func(i string) string { return strconv.Itoa(len(i)) },
expected: empty,
},
{
in: []string{"a"},
g: func(i string) string { return strconv.Itoa(len(i)) },
expected: [][]string{{"a"}},
},
{
in: []string{"a", "b", "aa", "bcd"},
g: func(i string) string { return strconv.Itoa(len(i)) },
expected: [][]string{{"a", "b"}, {"aa"}, {"bcd"}},
},
}

for i, tt := range tests {
t.Run(fmt.Sprintf("test %d", i), func(t *testing.T) {
out := GroupSlice(tt.in, tt.g)
require.Equal(t, tt.expected, out)
})
}
}

func TestSliceAny(t *testing.T) {
type test struct {
in []int
expectedOut []any
}

tests := []test{
{
[]int{},
[]any{},
},
{
[]int{1},
[]any{1},
},
}

for _, tt := range tests {
t.Run(fmt.Sprintf("inputQuery %v", tt.in), func(t *testing.T) {
out := SliceToAny(tt.in)
require.Equal(t, tt.expectedOut, out)
})
}
}
Loading

0 comments on commit c9743f5

Please sign in to comment.