<commit_before>package triplestore

import (
	"fmt"
	"math/rand"
	"reflect"
	"time"
)

const (
	predTag = "predicate"
	subTag  = "subject"
)

var random = rand.New(rand.NewSource(time.Now().UnixNano()))

// Convert a Struct or ptr to Struct into triples
// using field tags.
// For each struct's field a triple is created:
// - Subject: function first argument
// - Predicate: tag value
// - Literal: actual field value according to field's type
// Unsupported types are ignored
func TriplesFromStruct(sub string, i interface{}) (out []Triple) {
	val := reflect.ValueOf(i)

	var ok bool
	val, ok = getStructOrPtrToStruct(val)
	if !ok {
		return
	}

	st := val.Type()

	for i := 0; i < st.NumField(); i++ {
		field, fVal := st.Field(i), val.Field(i)
		if !fVal.CanInterface() {
			continue
		}

		intValue := reflect.ValueOf(fVal.Interface())
		if intValue.Kind() == reflect.Ptr && intValue.IsNil() {
			continue
		}

		pred := field.Tag.Get(predTag)
		if tri, ok := buildTripleFromVal(sub, pred, fVal); ok {
			out = append(out, tri)
		}

		tag, embedded := field.Tag.Lookup(subTag)
		fVal, ok := getStructOrPtrToStruct(fVal)
		if ok && embedded {
			embedSub := tag
			if tag == "rand" {
				embedSub = fmt.Sprintf("%x", random.Uint32())
			}
			tris := TriplesFromStruct(embedSub, fVal.Interface())<commit_msg>Seed random ID generator safe for concurrent use<commit_after>package triplestore

import (
	"fmt"
	"math/rand"
	"reflect"
	"time"
)

const (
	predTag = "predicate"
	subTag  = "subject"
)

func init() {
	rand.Seed(time.Now().UnixNano())
}

// Convert a Struct or ptr to Struct into triples
// using field tags.
// For each struct's field a triple is created:
// - Subject: function first argument
// - Predicate: tag value
// - Literal: actual field value according to field's type
// Unsupported types are ignored
func TriplesFromStruct(sub string, i interface{}) (out []Triple) {
	val := reflect.ValueOf(i)

	var ok bool
	val, ok = getStructOrPtrToStruct(val)
	if !ok {
		return
	}

	st := val.Type()

	for i := 0; i < st.NumField(); i++ {
		field, fVal := st.Field(i), val.Field(i)
		if !fVal.CanInterface() {
			continue
		}

		intValue := reflect.ValueOf(fVal.Interface())
		if intValue.Kind() == reflect.Ptr && intValue.IsNil() {
			continue
		}

		pred := field.Tag.Get(predTag)
		if tri, ok := buildTripleFromVal(sub, pred, fVal); ok {
			out = append(out, tri)
		}

		tag, embedded := field.Tag.Lookup(subTag)
		fVal, ok := getStructOrPtrToStruct(fVal)
		if ok && embedded {
			embedSub := tag
			if tag == "rand" {
				embedSub = fmt.Sprintf("%x", rand.Uint32())
			}
			tris := TriplesFromStruct(embedSub, fVal.Interface())
{'fraction_non_alphanumeric': 0.14814814814814814, 'fraction_numerical': 0.0022675736961451248, 'mean_word_length': 3.494057724957555, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, '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': '2694051', 'n_tokens_mistral': 1011, 'n_tokens_neox': 929, 'n_words': 258}