You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

94 lines
2.4 KiB

package neo4j
import (
"context"
"fmt"
"time"
)
// RecordEventAccess updates access tracking for an event in Neo4j.
// This creates or updates an AccessTrack node for the event.
func (n *N) RecordEventAccess(serial uint64, connectionID string) error {
cypher := `
MERGE (a:AccessTrack {serial: $serial})
ON CREATE SET a.lastAccess = $now, a.count = 1
ON MATCH SET a.lastAccess = $now, a.count = a.count + 1`
params := map[string]any{
"serial": int64(serial), // Neo4j uses int64
"now": time.Now().Unix(),
}
_, err := n.ExecuteWrite(context.Background(), cypher, params)
if err != nil {
return fmt.Errorf("failed to record event access: %w", err)
}
return nil
}
// GetEventAccessInfo returns access information for an event.
func (n *N) GetEventAccessInfo(serial uint64) (lastAccess int64, accessCount uint32, err error) {
cypher := "MATCH (a:AccessTrack {serial: $serial}) RETURN a.lastAccess AS lastAccess, a.count AS count"
params := map[string]any{"serial": int64(serial)}
result, err := n.ExecuteRead(context.Background(), cypher, params)
if err != nil {
return 0, 0, fmt.Errorf("failed to get event access info: %w", err)
}
ctx := context.Background()
if result.Next(ctx) {
record := result.Record()
if record != nil {
if la, found := record.Get("lastAccess"); found {
if v, ok := la.(int64); ok {
lastAccess = v
}
}
if c, found := record.Get("count"); found {
if v, ok := c.(int64); ok {
accessCount = uint32(v)
}
}
}
}
return lastAccess, accessCount, nil
}
// GetLeastAccessedEvents returns event serials sorted by coldness.
func (n *N) GetLeastAccessedEvents(limit int, minAgeSec int64) (serials []uint64, err error) {
cutoffTime := time.Now().Unix() - minAgeSec
cypher := `
MATCH (a:AccessTrack)
WHERE a.lastAccess < $cutoff
RETURN a.serial AS serial, a.lastAccess AS lastAccess, a.count AS count
ORDER BY (a.lastAccess + a.count * 3600) ASC
LIMIT $limit`
params := map[string]any{
"cutoff": cutoffTime,
"limit": limit,
}
result, err := n.ExecuteRead(context.Background(), cypher, params)
if err != nil {
return nil, fmt.Errorf("failed to get least accessed events: %w", err)
}
ctx := context.Background()
for result.Next(ctx) {
record := result.Record()
if record != nil {
if s, found := record.Get("serial"); found {
if v, ok := s.(int64); ok {
serials = append(serials, uint64(v))
}
}
}
}
return serials, nil
}