Open mgroves opened 1 year ago
My plan: a single document containing a list of usernames being followed.
Something like
key "jake::following"
{
"following" : ["username1", "username2", . . .]
}
(Although, the document can probably be an array instead of an object with a named array in it (or maybe a Map, List, Queue, Set via Data Structures))
Couchbase max document size is 20mb. BUT according to ChatGPT, this could accommodate over 1.1 million follows, assuming usernames are 15 characters on average:
See https://chat.openai.com/share/adac6ff1-1498-4102-8959-b6cc7a40f925
The current constraint is 100 characters. If EVERY user had a 100 character username, the limit would be 194,174 (again per ChatGPT).
So I don't think doc size is a problem, unless other data needs to be added to the follow (date/time, reason, notes, whatever else). Twitter, in fact, puts a cap of 5000 follows for most people. However, I may want to reevaluate the max size of username anyway (Twitter restricts to 15 characters, I think).
I think the more interesting issue would be checking this document to see if a give username is in it. I'm hoping that the aforementioned Data Structures will provide that efficiency (via the subdocument API).
Re: Data Structures, it might be a good idea to try BenchmarkDotNet, to see the performance impact, as well as compare/contrast the various data structures.
I ran some benchmarks on various ways to interact with a "following" document:
BenchmarkDotNet v0.13.6, Windows 10 (10.0.19045.3208/22H2/2022Update)
Intel Core i7-6700K CPU 4.00GHz (Skylake), 1 CPU, 8 logical and 4 physical cores
.NET SDK 7.0.304
[Host] : .NET 7.0.9 (7.0.923.32018), X64 RyuJIT AVX2
Job-UQZKSN : .NET 7.0.9 (7.0.923.32018), X64 RyuJIT AVX2
IterationCount=50
Method | Mean | Error | StdDev | Median |
---|---|---|---|---|
FindInList | 767.9 μs | 33.89 μs | 68.46 μs | 751.6 μs |
FindInSet | 777.2 μs | 58.50 μs | 118.17 μs | 764.5 μs |
FindInArray | 758.2 μs | 11.72 μs | 22.59 μs | 753.4 μs |
AddToSet | 26,175.7 μs | 8,164.13 μs | 16,491.95 μs | 19,447.9 μs |
AddToList | 4,813.2 μs | 769.36 μs | 1,554.14 μs | 4,635.8 μs |
AddToArrayOptimistic | 5,120.1 μs | 813.25 μs | 1,642.81 μs | 5,182.3 μs |
AddToArrayPessimistic | 12,774.7 μs | 1,290.59 μs | 2,607.05 μs | 12,890.9 μs |
I'm leaning towards AddToArrayOptimistic
, but List might work too. 🤔
Set is the ideal choice, since it enforces uniqueness. However, you can see that AddToSet
is the slowest (26ms isn't terribly slow, so it might be okay).
List is pretty fast, but AddToList
as I wrote it does not do any locking, so there is a chance of race conditions.
AddToArrayOptimistic uses optimistic locking; it doesn't use any of the built in data structures. Of course, with optimistic locking, cas mismatch is possible, so that has to be accounted for in code. But I think optimistic locking in this situation in reality will almost never have a cas mismatch.
POST /api/profiles/:username/follow
Authentication required, returns a Profile
No additional parameters required