Manage Cache collection by multiple properties - c#

I have Sensor class which contains few properties: id, a, b.
Another class called SensorCache and responsible for manage in memory cache for my sensor collection.
SensorCache implements "Cache aside pattern" see here
SensorCache works in traditional way - each Sensor request (the requests made by the id property) first goes to SensorCache:
if it already exists in memory - SensorCache return it
if not in memory, it brings the required Sensor from my DB, save into memory cache object (represented by `Dictionary') and return it.
Currently my dictionary key is based on the Sensor.id field.
I got a new requirement to return a Sensor by 2 fields (a and b) and keep my cache logic.
My cache object currently built to search by single property (Sensor.id) so I need to think about new structure which able to search in memory by 2 different options: Sensor.id or 'Sensor.a' and 'Sensor.b' pairs.
What is the best approach to handle this?
I thought about holding two different objects, one for each kind of search but this approach will consume much more memory (x2) so I want to hear another ideas before doing it.

You can write a separate class that implements IEquatable and overrides GetHashCode (and sometimes you have to, to achieve the required performance) but in this simple case, it sounds like you could use Tuple, that is, Dictionary<Tuple<(type of a), (type of b)>, Sensor>.

Related

How to deal with IEnumerables/Arrays/Collections in Fluxor State?

I'm currently trying to implement Fluxor for my Blazor WASM app and all the instructions/tutorials I found recommended something like this example for the Store:
public record AppStore {
int ClickCounter,
bool IsLoading,
WeatherForecast[]? Forecasts
}
and then only talk about initial state and updates only happen to the bool and the int while the array is only ever replaced outright. I.e. the examples always fetch the complete data from the server, e.g. a 100 entries.
Now, here's my question: How do I properly deal with the array in my reducer when I have already 100 entries in there and only want do add/update/delete one? Is that even a good idea in the first place?
The best thing to do is to use ImmutableList<T> or ImmutableArray<T> instead, as this class is optimised for the purpose of returning a new instance that includes old data but without having to copy the elements.
I've recently released a new library called Reducible that helps to create complex state reducers. It results in fewer updates (e.g. a new parent object isn't created if an item in the list is not replaced).
https://github.com/mrpmorris/Reducible/blob/master/README.md

Preventing a WCF client from adding/removing objects from a list

In my system, I need my clients to be able to get a List of objects, representative of the service states/context.
Say you have the following action done by a given client to retrieve the context:
List<someObjects> aList = GetListOfObjects();
Now the client is able to retrieve aList, but it can also modify this list before sending it back through the channel, which I would like to prevent (as it would not be representative of the system anymore). Therefore, the client should not be able to do:
aList.RemoveAt(1); // Should not be possible to remove object from this list
SetListOfObjects(aList);
I thought I could create a readonly "aList" class, but I still want to be able to modify the objects' properties, so I don't thing it is the right thing to do.
One idea is to actually create a class, where all objects from the aList would be properties instead. That way, the class would impose a structure that could not be modified by the client. However, the system's context may vary (depending on the hardware being used), meaning this class would need to be dynamically created.
I however do not want to lose the type safety and hence would rather not use the dynamic or expando Objects.
Maybe using something of the sort is a good idea here, see answer from danijels. But I am not sure the type safety would be preserved by doing so.

Should I use linked list or list and how do I serialize it.

This is for c#
I'm an old dinosaur, writing 360 assembler since the 70's, trying to write stuff for the PC. Along the way I am replacing my old write it myself thinking with use the existing infrastructure.
Here is what I have now. Two objects, System and Planet. A field in System has a pointer to the next System, there is also a second chain of Systems that meet current selection criteria. Also System has a pointer to Planet and Planet has a pointer to the next Planet. Planet also has a chain of all planets.
Now the questions. Should I use lists and have C# handle all the linking etc. I'm fairly sure 1 object instance can be in multiple lists, so I can have 1 list of all systems and a second list of selected systems. Plus have a list of Planets in the system and another list of all Planets.
I also want to save this mess to disk. I've spent some time looking at serialization and it appears to be great at saving all the instances in a list, but things break down when you want to serialize multiple classes. Am I missing something basic, just a yes will send me back to looking, or do I have to roll my own?
I don't want code examples, just a gentle puch in the direction I should be looking at.
I would simply create two classes, one being the System with a List<Planet> containing all its planets and the other one being the Planet, containing a reference to his system (if one is required). The systems are themselves saved in a List<System>. Like the planets they could hold a reference to their parent so they have access to the list, but if they don't need to, its fine.
Saving this stuff should be three lines of code with a serializing system of your choice, either in text or binary (Json.Net, the Xml stuff .Net provides, yaml, binary formatter...).
Linked lists are not worth the implementation, they aren't as useful as dynamic arrays (like the List<T> in System.Collections.Generic or the Vector<T> in C++) which resize themselves when needed, and they aren't that easy to keep track of. They definetly have applications but this is not one of them IMO.
Should I use linked list or list...
The answer depends on what your object represents and how you are going to use it. For example, if I was representing houses, and the people who live at each house; then I might choose to have a collection of House objects. I'm using collection as a generic term there: specifically, I would probably use List<T> from the System.Collections.Generic namespace (where T can represent any type, so it would be a List<House> in this case), unless I needed something more specific like a Stack<T>, Queue<T>, Dictionary<T,U>, etc, etc.
Notice how in this approach, each House doesn't know which house is next, because the whole concept of 'next' relates to the collection of houses: each individual house doesn't need to know where it is in the collection - that's the responsibility of the collection. This is a design principle called "separation of concerns".
For example, if I wanted to create a different collection of House objects (e.g. the ones with red front doors), I could do so by creating a new collection, referring to the same House objects; whereas with the approach mentioned of an object having a reference to the next one, I would have to create a different House object because the next value would be different in those two collections.
Using List<T> allows you to focus on writing your classes, instead of having to write the implementation of the collection.
There are also performance reasons against using linked lists unless you only plan to access the data in sequential order.
Each House has-a collection of people. So I might put a property on House called People, of type List<Person>. And if I needed to get to the house that the person was associated with, I could have a property on Person called House, of type House.
I hope this structure of Houses and People corresponds to your scenario with Systems and Planets.
Maybe also worth looking at When should I use a List vs a LinkedList
...and how do I serialize it.
Plenty on the internet, try these...
How to Serialize List<T>?
https://www.thomaslevesque.com/2009/06/12/c-parentchild-relationship-and-xml-serialization/
Hope this helps to get you started.
From the sound of it, I will create class of System, Planet with one to many reference of planets in System (List here). In order to avoid strong coupling between System and Planet, One can look at Chain of Responsibility pattern.
Saving this data to database one can serialise using Json.Net (newtonsoft). SQL server supports directly putting json array.
Pseudo code:
class Planet {
public Planet(System system) {System = system;}
public System System {get; private set;} // singleton
}
class System {
public Planet Planet {get; set;}
// list of planets
private List<Planet> planets = new List<Planet>();
public List<Planet> Planets { get {return planets; } }
}

Utilisation of a Dictionary like class

For the purpose of XML serialisation I had to disband a Dictionary collection I was using. I wrote a very straightforward alternative which consists of 2 classes:
NameValueItem: contains Name (Key) and Value
NameValueCollection: derived from CollectionBase and maintains a collection of NameValueItem objects.
I've included some standard methods to help maintain the collection (Add, Contains and Remove). So just like most Dictionary types, the Name (or Key) is unique:
public bool Contains(NameValueItem item)
{
foreach (NameValueItem lItem in List)
if(lItem.Name.Equals(item.Name))
return true;
return false;
}
Add uses this Contains method to determine whether to include a given item into the collection:
public void Add(NameValueItem item)
{
if (!Contains(item))
List.Add(item);
}
As bog standard, straightforward and easy as this code appears it's proving to be a little sluggish. Is there anything that can be done to improve the performance of this? Or alternatives I could use?
I was considering creating a NameValueHashSet, which is derived from HashSet.
Optional...:
I had a question which I was going to ask in a separate thread, but I'll leave it up to you as to whether you'd like to address it or not.
I wanted to add 2 properties to the NameValueCollection, Names and Values, which return a List of strings from the Collection of NameValueItem objects. Instead I built them into methods GetNames() and GetValues(), as I have to build the collection (i.e. create a List (names/values), iterate over collection adding names/value to List and return List).
Is this a better alternative? In terms of good coding practise, performance, etc.? As my thoughts regarding properties has always been to have it as stripped back as possible, that only references, arithmetic, etc. should exist, with no layers of processes. If that is the case, then it should be built into a method. Thoughts?
Perhaps you shouldn't try to rebuild what the framework already provides? Your implementation of a dictionary is going to perform poorly as it does not scale. The built in Dictionary<TKey, TValue> has O(1) access performance and for most insert and delete operations (unless there are collisions or the internal storage must be expanded).
You can extend the existing dictionary to provide XML serialization support; see this question and answers: Serialize Class containing Dictionary member
As for your second question - Dictionary already provides methods for getting an IEnumerable of the keys and values. This enumerates the keys and/or values as requested by the caller; that is delayed execution and is likely the preferred method over building a full List every time (which requires iterating through all the elements in the dictionary). If the caller wants a list then they just do dictionary.Values.ToList().

Db4O activation depth, Faq, Best Practise for Web Application

Our database includes 4,000,000 records (sql server) and it's physical size is 550 MB .
Entities in database are related each other as graph style. When i load an entity from db with 5 level depth there is a problem (all records are loaded).
Is there any mechanism like Entity Framework( Include("MyProperty.ItsProperty"))
What is the best Types for using with db4O databases?
Is there any issue for Guid, Generic Collections?
Is there any best practise for WebApplication with db4o? Session Containers+EmbeddedDb4ODb or Client/ServerDb4O?
Thx for help..
Thx for good explanation. But i want to give my exact problem as a sample:
I have three entities: (N-N relationship. B is an intersection Entity. Concept:Graph)
class A
{
public B[] BList;
public int Number;
public R R;
}
class B
{
public A A;
public C C;
public D D;
public int Number;
}
class C
{
public B[] BList;
public E E;
public F F;
public int Number;
}
I want to query dbContext.A.Include("BList.C.BList.A").Include("BList.C.E.G").Where(....)
I want to get :A.BList.C.BList.A.R
But I dont want to get :A.R
I want to get :A.BList.C.E.G
But I dont want to get :A.BList.C.F
I want to get :A.BList.C.E.G
But I dont want get :A.BList.D
Note:this requirements can change a query to another query
Extra question is there any possibility to load
A.BList[#Number<120].C.BList.A[#Number>100] Super syntax :)
Activation: As you said db4o uses it's activation-mechanism to control which objects are loaded. To prevent that to many objects are loaded there are different strategies.
Lower the global default activation-depth: configuration.Common.ActivationDepth = 2 Then use the strategies below to activate objects on need.
Use class-specific activation configuration like cascading activation, minimum and maximun activation-depth etc.
Activate objects explicit on demand: container.Activate(theObject,5)
However all these stuff is rather painful on complex object graphs. The only strategy to get away from that pain is transparent activation. Create an attribute like TransparentlyActivated. Use this attribute to mark your stored classes. Then use the db4otool to enhance your classes. Add the db4otool-command to the Post-Build events in Visual Studio: Like 'PathTo\Db4oTool.exe -ta -debug -by-attribute:YourNamespace.TransparentlyActivated $(TargetPath)
Guid, Generic Collections:
No (in Version 7.12 or 8.0). However if you store your own structs: Those are handled very poorly by db4o
WebApplication: I recommend an embedded-container, and then a session-container for each request.
Update for extended question part
To your case. For such complex activation schema I would use transparent activation.
I assume you are using properties and not public fields in your real scenario, otherwise transparent persistence doesn't work.
The transparent activation basically loads an object in the moment a method/property is called the first. So when you access the property A.R then A itself it loaded, but not the referenced objects. I just go through a few of you access patterns to show what I mean:
Getting 'A.BList.C.BList.A.R'
A is loaded when you access A.BList. The BList array is filled with unactivate objects
You keep navigating further to BList.C. At this moment the BList object is loaded
Then you access C.BList. db4o loads the C-object
And so on and so forth.
So when you get 'A.BList.C.BList.A.R' then 'A.R' isn't loaded
A unloaded object is represented by an 'empty'-shell object, which has all values set to null or the default value. Arrays are always fully loaded, but first filled with unactivated objects.
Note that theres no real query syntax to do some kind of elaborate load requests. You load your start object and then pull stuff in as you need it.
I also need to mention that this kind of access will perform terrible over the network with db4o.
Yet another hint. If you want to do elaborate work on a graph-structure, you also should take a look at graph databases, like Neo4J or Sones Graph DB

Categories

Resources