<commit_before>package main

import (
	"fmt"
	"log"
	"net"
	"net/http"
	"strconv"
	"strings"
	"sync"
	"time"
)

type dirAliases struct {
	m                 map[string]FileServer
	mu                sync.RWMutex
	FileServerFactory fileServerFactory
}

func (da *dirAliases) List() []string {
	da.mu.RLock()
	defer da.mu.RUnlock()
	aliases := make([]string, 0, len(da.m))
	for alias := range da.m {
		aliases = append(aliases, alias)
	}
	return aliases
}

// Get retrieves the path for the given alias.
// It returns "" if the alias doesn't exist.
func (da *dirAliases) Get(alias string) string {
	da.mu.RLock()
	defer da.mu.RUnlock()
	fs, ok := da.m[alias]
	if !ok {
		return ""
	}
	return fs.Root()
}

// Put registers an alias for the given path.
// It returns true if the alias already exists.
func (da *dirAliases) Put(alias string, path string) bool {
	da.mu.Lock()
	defer da.mu.Unlock()
	_, ok := da.m[alias]

	fs := da.FileServerFactory(path)
	da.m[alias] = fs
	return ok
}

// Delete removes an existing alias.
// It returns true if the alias existed.
func (da *dirAliases) Delete(alias string) bool {
	da.mu.RLock()
	defer da.mu.RUnlock()
	_, ok := da.m[alias]
	delete(da.m, alias)
	return ok
}

func (da *dirAliases) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if !(strings.Count(r.URL.Path, "/") >= 2 && len(r.URL.Path) > 2) {
		http.NotFound(w, r)
		return
	}
	slashIndex := strings.Index(r.URL.Path[1:], "/")
	if slashIndex == -1 {
		http.NotFound(w, r)
		return
	}
	alias := r.URL.Path[1 : slashIndex+1]
	r.URL.Path = r.URL.Path[1+slashIndex:]

	da.mu.RLock()
	defer da.mu.RUnlock()
	fs, ok := da.m[alias]
	if !ok {
		http.Error(w, fmt.Sprintf("alias %q not found", alias), http.StatusNotFound)
		return
	}
	fs.ServeHTTP(w, r)
}

func newDirAliases() *dirAliases {
	return &dirAliases{
		m:                 make(map[string]FileServer),
		FileServerFactory: stdFileServerFactory,
	}
}

type dirServer struct {
	DirAliases *dirAliases
	Addr       string
	Port       uint16
	srv        *http.Server
	ln         net.Listener
	started    chan struct{}
}

func newDirServer(addr string) *dirServer {
	return &dirServer{
		DirAliases: newDirAliases(),
		Addr:       addr,
		started:    make(chan struct{}),
	}
}

func (ds *dirServer) ListenAndServe() error {
	ln, err := net.Listen("tcp", ds.Addr)
	if err != nil {
		return err
	}
	ds.Addr = ln.Addr().String()
	_, sport, err := net.SplitHostPort(ds.Addr)
	if err != nil {
		return err
	}
	port, err := strconv.Atoi(sport)
	if err != nil {
		return err
	}
	ds.Port = uint16(port)
	ds.srv = &http.Server{
		Handler: ds.DirAliases,
	}
	ds.ln = tcpKeepAliveListener{ln.(*net.TCPListener)}

	close(ds.started)
	if err := ds.srv.Serve(ds.ln); err != nil {
		return err
	}
	return nil
}

func (ds *dirServer) Close() error {
	return ds.ln.Close()
}
<commit_msg>Close existing connections when shutting down http server<commit_after>package main

import (
	"fmt"
	"log"
	"net"
	"net/http"
	"strconv"
	"strings"
	"sync"
	"time"
)

type dirAliases struct {
	m                 map[string]FileServer
	mu                sync.RWMutex
	FileServerFactory fileServerFactory
}

func (da *dirAliases) List() []string {
	da.mu.RLock()
	defer da.mu.RUnlock()
	aliases := make([]string, 0, len(da.m))
	for alias := range da.m {
		aliases = append(aliases, alias)
	}
	return aliases
}

// Get retrieves the path for the given alias.
// It returns "" if the alias doesn't exist.
func (da *dirAliases) Get(alias string) string {
	da.mu.RLock()
	defer da.mu.RUnlock()
	fs, ok := da.m[alias]
	if !ok {
		return ""
	}
	return fs.Root()
}

// Put registers an alias for the given path.
// It returns true if the alias already exists.
func (da *dirAliases) Put(alias string, path string) bool {
	da.mu.Lock()
	defer da.mu.Unlock()
	_, ok := da.m[alias]

	fs := da.FileServerFactory(path)
	da.m[alias] = fs
	return ok
}

// Delete removes an existing alias.
// It returns true if the alias existed.
func (da *dirAliases) Delete(alias string) bool {
	da.mu.RLock()
	defer da.mu.RUnlock()
	_, ok := da.m[alias]
	delete(da.m, alias)
	return ok
}

func (da *dirAliases) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if !(strings.Count(r.URL.Path, "/") >= 2 && len(r.URL.Path) > 2) {
		http.NotFound(w, r)
		return
	}
	slashIndex := strings.Index(r.URL.Path[1:], "/")
	if slashIndex == -1 {
		http.NotFound(w, r)
		return
	}
	alias := r.URL.Path[1 : slashIndex+1]
	r.URL.Path = r.URL.Path[1+slashIndex:]

	da.mu.RLock()
	defer da.mu.RUnlock()
	fs, ok := da.m[alias]
	if !ok {
		http.Error(w, fmt.Sprintf("alias %q not found", alias), http.StatusNotFound)
		return
	}
	fs.ServeHTTP(w, r)
}

func newDirAliases() *dirAliases {
	return &dirAliases{
		m:                 make(map[string]FileServer),
		FileServerFactory: stdFileServerFactory,
	}
}

type dirServer struct {
	DirAliases *dirAliases
	Addr       string
	Port       uint16
	srv        *http.Server
	ln         net.Listener
	started    chan struct{}
}

func newDirServer(addr string) *dirServer {
	return &dirServer{
		DirAliases: newDirAliases(),
		Addr:       addr,
		started:    make(chan struct{}),
	}
}

func (ds *dirServer) ListenAndServe() error {
	ln, err := net.Listen("tcp", ds.Addr)
	if err != nil {
		return err
	}
	ds.Addr = ln.Addr().String()
	_, sport, err := net.SplitHostPort(ds.Addr)
	if err != nil {
		return err
	}
	port, err := strconv.Atoi(sport)
	if err != nil {
		return err
	}
	ds.Port = uint16(port)
	ds.srv = &http.Server{
		Handler: ds.DirAliases,
	}
	ds.ln = &connsCloserListener{
		Listener: tcpKeepAliveListener{ln.(*net.TCPListener)},
	}

	close(ds.started)
	if err := ds.srv.Serve(ds.ln); err != nil {
		return err
	}
	return nil
}

func (ds *dirServer) Close() error {
	return ds.ln.Close()
}

type connsCloserListener struct {
	net.Listener
	conns []net.Conn
}

func (ln *connsCloserListener) Accept() (c net.Conn, err error) {
	c, err = ln.Listener.Accept()
	if err != nil {
		return
	}
	ln.conns = append(ln.conns, c)
	return c, nil
}

func (ln *connsCloserListener) Close() error {
	for _, c := range ln.conns {
		if err := c.Close(); err != nil {
			log.Println(err)
		}
	}
	ln.conns = nil
	return ln.Listener.Close()
}

{'fraction_non_alphanumeric': 0.1497074122236671, 'fraction_numerical': 0.0039011703511053317, 'mean_word_length': 3.2028688524590163, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3346164', 'n_tokens_mistral': 2455, 'n_tokens_neox': 2374, 'n_words': 607}