Compare commits

..

No commits in common. "master" and "v1.0.0" have entirely different histories.

17 changed files with 10 additions and 230 deletions

View File

@ -1,65 +0,0 @@
name: Release
on:
push:
tags:
- 'v*'
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: '9.0.x'
- name: Restore dependencies
run: dotnet restore Firefly.sln
- name: Build
run: |
chmod +x build-all.sh
./build-all.sh
- name: Create Release
uses: softprops/action-gh-release@v1
with:
name: Firefly v1.0.0 - Initial Release
body: |
# Firefly v1.0.0 - Initial Release
We're excited to announce the initial release of Firefly! This version includes the core functionality of our application.
## Features
- Native library support for enhanced performance
- Self-contained executable builds
- Cross-platform compatibility (Linux, macOS)
## Installation
Choose the appropriate build for your platform from the assets below.
## System Requirements
- .NET 9.0 Runtime (for non-self-contained builds)
- Linux x64, macOS x64, or Windows x64
## Known Issues
- None reported
## What's Next
- Additional platform support
- Performance optimizations
- Enhanced documentation
## Feedback
We welcome your feedback and bug reports. Please use the issue tracker to report any problems.
files: |
artifacts/exe/*
artifacts/native/*
draft: false
prerelease: false

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -227,13 +227,6 @@
<param name="args">Command arguments containing the key</param> <param name="args">Command arguments containing the key</param>
<returns>The popped value or nil if the list is empty</returns> <returns>The popped value or nil if the list is empty</returns>
</member> </member>
<member name="M:Firefly.Firefly.HandleLLengthCommand(System.String)">
<summary>
Handles the LLEN command which returns the length of a list.
</summary>
<param name="args">Command arguments containing the key</param>
<returns>The length of the list or 0 if the key does not exist</returns>
</member>
<member name="M:Firefly.Firefly.HandleLRangeCommand(System.String)"> <member name="M:Firefly.Firefly.HandleLRangeCommand(System.String)">
<summary> <summary>
Handles the LRANGE command which returns a range of elements from a list. Handles the LRANGE command which returns a range of elements from a list.
@ -320,11 +313,6 @@
<param name="key">The key to execute the action on</param> <param name="key">The key to execute the action on</param>
<param name="action">The action to execute</param> <param name="action">The action to execute</param>
</member> </member>
<member name="M:Firefly.Firefly.DisplayFireflyArt">
<summary>
Displays Firefly ASCII art in the console
</summary>
</member>
<member name="M:Firefly.Firefly.HandleAuthCommand(System.String,System.String)"> <member name="M:Firefly.Firefly.HandleAuthCommand(System.String,System.String)">
<summary> <summary>
Handles the AUTH command which authenticates a client. Handles the AUTH command which authenticates a client.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -227,13 +227,6 @@
<param name="args">Command arguments containing the key</param> <param name="args">Command arguments containing the key</param>
<returns>The popped value or nil if the list is empty</returns> <returns>The popped value or nil if the list is empty</returns>
</member> </member>
<member name="M:Firefly.Firefly.HandleLLengthCommand(System.String)">
<summary>
Handles the LLEN command which returns the length of a list.
</summary>
<param name="args">Command arguments containing the key</param>
<returns>The length of the list or 0 if the key does not exist</returns>
</member>
<member name="M:Firefly.Firefly.HandleLRangeCommand(System.String)"> <member name="M:Firefly.Firefly.HandleLRangeCommand(System.String)">
<summary> <summary>
Handles the LRANGE command which returns a range of elements from a list. Handles the LRANGE command which returns a range of elements from a list.
@ -320,11 +313,6 @@
<param name="key">The key to execute the action on</param> <param name="key">The key to execute the action on</param>
<param name="action">The action to execute</param> <param name="action">The action to execute</param>
</member> </member>
<member name="M:Firefly.Firefly.DisplayFireflyArt">
<summary>
Displays Firefly ASCII art in the console
</summary>
</member>
<member name="M:Firefly.Firefly.HandleAuthCommand(System.String,System.String)"> <member name="M:Firefly.Firefly.HandleAuthCommand(System.String,System.String)">
<summary> <summary>
Handles the AUTH command which authenticates a client. Handles the AUTH command which authenticates a client.

View File

@ -8,13 +8,6 @@ namespace Firefly
public partial class Firefly public partial class Firefly
{ {
#region Backup System #region Backup System
// Track if data has been modified since last backup
private static volatile bool dataModified = false;
// Debounce period in milliseconds for data modification backups
private static readonly int dataModificationBackupDelayMs = 5000;
// Timer for debouncing data modification backups
private static System.Timers.Timer? modificationBackupTimer;
static void InitializeBackupSystem() static void InitializeBackupSystem()
{ {
// Create backup directory if it doesn't exist // Create backup directory if it doesn't exist
@ -40,21 +33,7 @@ namespace Firefly
backupTimer.AutoReset = true; backupTimer.AutoReset = true;
backupTimer.Start(); backupTimer.Start();
// Set up data modification backup timer
modificationBackupTimer = new System.Timers.Timer(dataModificationBackupDelayMs);
modificationBackupTimer.Elapsed += (sender, e) =>
{
if (dataModified)
{
BackupData();
dataModified = false;
}
modificationBackupTimer.Stop(); // Stop timer after backup
};
modificationBackupTimer.AutoReset = false;
Console.WriteLine($"Automatic backup system initialized (every {autoBackupIntervalMinutes} minutes)"); Console.WriteLine($"Automatic backup system initialized (every {autoBackupIntervalMinutes} minutes)");
Console.WriteLine($"Data modification backup system initialized (after {dataModificationBackupDelayMs/1000} seconds of inactivity)");
Console.WriteLine($"Keeping up to {maxBackupFiles} backup files"); Console.WriteLine($"Keeping up to {maxBackupFiles} backup files");
// Register backup on exit // Register backup on exit
@ -68,22 +47,6 @@ namespace Firefly
}; };
} }
// Call this method whenever data is modified
internal static void MarkDataAsModified()
{
if (!backupsEnabled)
return;
dataModified = true;
// Reset and start the timer to debounce multiple rapid changes
if (modificationBackupTimer != null)
{
modificationBackupTimer.Stop();
modificationBackupTimer.Start();
}
}
static void LoadDataFromBackup() static void LoadDataFromBackup()
{ {
if (!backupsEnabled) if (!backupsEnabled)

View File

@ -188,10 +188,7 @@ namespace Firefly
case "LINDEX": case "LINDEX":
return HandleLIndexCommand(parts.Length > 1 ? string.Join(" ", parts.Skip(1)) : ""); return HandleLIndexCommand(parts.Length > 1 ? string.Join(" ", parts.Skip(1)) : "");
case "LLEN":
return HandleLLengthCommand(parts.Length > 1 ? parts[1] : "");
case "LRANGE": case "LRANGE":
return HandleLRangeCommand(parts.Length > 1 ? string.Join(" ", parts.Skip(1)) : ""); return HandleLRangeCommand(parts.Length > 1 ? string.Join(" ", parts.Skip(1)) : "");

View File

@ -27,11 +27,10 @@ namespace Firefly
{ {
var hash = GetOrCreateHash(key); var hash = GetOrCreateHash(key);
bool isNewField = hash.TryAdd(field, value); bool isNewField = hash.TryAdd(field, value);
if (!isNewField) if (!isNewField)
{
hash[field] = value; hash[field] = value;
}
MarkDataAsModified();
return Encoding.UTF8.GetBytes($":{(isNewField ? 1 : 0)}\r\n"); return Encoding.UTF8.GetBytes($":{(isNewField ? 1 : 0)}\r\n");
} }
@ -92,11 +91,10 @@ namespace Firefly
{ {
bool removed = hash.TryRemove(field, out _); bool removed = hash.TryRemove(field, out _);
if (removed)
MarkDataAsModified();
if (hash.IsEmpty) if (hash.IsEmpty)
{
HashStoreRemove(key); HashStoreRemove(key);
}
return Encoding.UTF8.GetBytes($":{(removed ? 1 : 0)}\r\n"); return Encoding.UTF8.GetBytes($":{(removed ? 1 : 0)}\r\n");
} }
@ -199,8 +197,6 @@ namespace Firefly
return Encoding.UTF8.GetBytes($"-ERR internal error: {ex.Message}\r\n"); return Encoding.UTF8.GetBytes($"-ERR internal error: {ex.Message}\r\n");
} }
MarkDataAsModified();
return Encoding.UTF8.GetBytes("+OK\r\n"); return Encoding.UTF8.GetBytes("+OK\r\n");
} }
@ -224,12 +220,7 @@ namespace Firefly
} }
} }
var hash = hashStoreShards[shardIndex].GetOrAdd(key, _ => new ConcurrentDictionary<string, string>()); return hashStoreShards[shardIndex].GetOrAdd(key, _ => new ConcurrentDictionary<string, string>());
if (hash.IsEmpty)
MarkDataAsModified();
return hash;
} }
/// <summary> /// <summary>
@ -263,12 +254,7 @@ namespace Firefly
private static bool HashStoreRemove(string key) private static bool HashStoreRemove(string key)
{ {
int shardIndex = GetShardIndex(key); int shardIndex = GetShardIndex(key);
bool result = hashStoreShards[shardIndex].TryRemove(key, out _); return hashStoreShards[shardIndex].TryRemove(key, out _);
if (result)
MarkDataAsModified();
return result;
} }
#endregion #endregion
#endregion #endregion

View File

@ -152,26 +152,6 @@ namespace Firefly
: Encoding.UTF8.GetBytes("$-1\r\n"); : Encoding.UTF8.GetBytes("$-1\r\n");
} }
/// <summary>
/// Handles the LLEN command which returns the length of a list.
/// </summary>
/// <param name="args">Command arguments containing the key</param>
/// <returns>The length of the list or 0 if the key does not exist</returns>
static byte[] HandleLLengthCommand(string args)
{
if (string.IsNullOrWhiteSpace(args))
{
return Encoding.UTF8.GetBytes("-ERR wrong number of arguments for 'llen' command\r\n");
}
string key = args.Trim();
// Change to use the generic method correctly by returning the length
int length = ListStoreWithReadLock(key, list => list.Count);
return Encoding.UTF8.GetBytes($":{length}\r\n");
}
/// <summary> /// <summary>
/// Handles the LRANGE command which returns a range of elements from a list. /// Handles the LRANGE command which returns a range of elements from a list.
/// </summary> /// </summary>
@ -548,13 +528,6 @@ namespace Firefly
{ {
throw new InvalidOperationException($"Key '{key}' already exists with a different type"); throw new InvalidOperationException($"Key '{key}' already exists with a different type");
} }
var newList = new List<string>();
if (listStoreShards[shardIndex].TryAdd(key, newList))
{
MarkDataAsModified();
return newList;
}
} }
return listStoreShards[shardIndex].GetOrAdd(key, _ => []); return listStoreShards[shardIndex].GetOrAdd(key, _ => []);
@ -594,12 +567,7 @@ namespace Firefly
listStoreLocks[shardIndex].EnterWriteLock(); listStoreLocks[shardIndex].EnterWriteLock();
try try
{ {
bool result = listStoreShards[shardIndex].TryRemove(key, out _); return listStoreShards[shardIndex].TryRemove(key, out _);
if (result)
MarkDataAsModified();
return result;
} }
finally finally
{ {
@ -620,8 +588,6 @@ namespace Firefly
{ {
var list = GetOrCreateList(key); var list = GetOrCreateList(key);
action(list); action(list);
MarkDataAsModified();
} }
finally finally
{ {

View File

@ -9,9 +9,6 @@ namespace Firefly
#region Server Management #region Server Management
static async Task StartServerAsync() static async Task StartServerAsync()
{ {
// Display Firefly ASCII art
DisplayFireflyArt();
// Set up server on specified port // Set up server on specified port
var listener = new TcpListener(IPAddress.Parse(bindAddress), serverPort); var listener = new TcpListener(IPAddress.Parse(bindAddress), serverPort);
listener.Start(); listener.Start();
@ -308,38 +305,6 @@ namespace Firefly
} }
} }
} }
/// <summary>
/// Displays Firefly ASCII art in the console
/// </summary>
static void DisplayFireflyArt()
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine(
" ,,_\n" +
" zd$$??=\n" +
" z$$P? F:`c, _\n" +
" d$$, `c'cc$$i ,cd$?R\n" +
" $$$$ cud$,?$$$i ,=P'2?z '\n" +
" $` ` ?$$$,?$$$. ,-''`>, bzP\n" +
" 'cLdb,?$$,?$$$ ,h' 'I$'J$P\n" +
" ... `?$$$,`$$,`$$h $$PxrF'd$'\n" +
" d$PP``?-,`?$$,?$h`$$,,$$'$F44'\n" +
" ?,,_`=4c,?=,`?hu?$`?L4$'? '\n" +
" ```?==``=-`` ```-`'_,,,,\n" +
" .ccu?m?e?JC,-,\"=?\n" +
" ```=='?'\n");
Console.WriteLine(@"
");
Console.ResetColor();
}
#endregion #endregion
} }
} }

View File

@ -88,9 +88,6 @@ namespace Firefly
int shardIndex = GetShardIndex(key); int shardIndex = GetShardIndex(key);
stringStoreShards[shardIndex][key] = value; stringStoreShards[shardIndex][key] = value;
MarkDataAsModified();
return true; return true;
} }
@ -114,12 +111,7 @@ namespace Firefly
private static bool StringStoreRemove(string key) private static bool StringStoreRemove(string key)
{ {
int shardIndex = GetShardIndex(key); int shardIndex = GetShardIndex(key);
bool result = stringStoreShards[shardIndex].TryRemove(key, out _); return stringStoreShards[shardIndex].TryRemove(key, out _);
if (result)
MarkDataAsModified();
return result;
} }
#endregion #endregion
#endregion #endregion