Generics Node declaration - c#

Microsoft gives this as an Bubble sort example for learning generics. It makes sense until I get to lines 76 and 77. How are those declarations possible? Node is a class. Don't you have to instantiate it with new?
How would you optimize the sort? Which is part is generic and which is non-generic?
1 public class GenericList<T> : System.Collections.Generic.IEnumerable<T>
2 {
3 protected Node head;
4 protected Node current = null;
5
6 // Nested class is also generic on T
7 protected class Node
8 {
9 public Node next;
10 private T data; //T as private member datatype
11
12 public Node(T t) //T used in non-generic constructor
13 {
14 next = null;
15 data = t;
16 }
17
18 public Node Next
19 {
20 get { return next; }
21 set { next = value; }
22 }
23
24 public T Data //T as return type of property
25 {
26 get { return data; }
27 set { data = value; }
28 }
29 }
30
31 public GenericList() //constructor
32 {
33 head = null;
34 }
35
36 public void AddHead(T t) //T as method parameter type
37 {
38 Node n = new Node(t);
39 n.Next = head;
40 head = n;
41 }
42
43 // Implementation of the iterator
44 public System.Collections.Generic.IEnumerator<T> GetEnumerator()
45 {
46 Node current = head;
47 while (current != null)
48 {
49 yield return current.Data;
50 current = current.Next;
51
52 }
53 }
54
55 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
56 {
57 return GetEnumerator();
58 }
59 }
60
61 public class SortedList<T> : GenericList<T> where T : System.IComparable<T>
62 {
63 // A simple, unoptimized sort algorithm that
64 // orders list elements from lowest to highest:
65
66 public void BubbleSort()
67 {
68 if (null == head || null == head.Next)
69 {
70 return;
71 }
72 bool swapped;
73
74 do
75 {
76 Node previous = null;
77 Node current = head;
78
79
80 //Console.WriteLine(previous.GetType());
81 //Console.ReadLine();
82
83 swapped = false;
84
85
86 //Debug.WriteLine(p);
87 //Debug.WriteLine("Testing " + current.ToString());
88
89 while (current.next != null)
90 {
91 // Because we need to call this method, the SortedList
92 // class is constrained on IEnumerable<T>
93 if (current.Data.CompareTo(current.next.Data) > 0)
94 {
95 Node tmp = current.next;
96 current.next = current.next.next;
97 tmp.next = current;
98
99 if (previous == null)
100 {
101 head = tmp;
102 }
103 else
104 {
105 previous.next = tmp;
106 }
107 previous = tmp;
108 swapped = true;
109 }
110 else
111 {
112 previous = current;
113 current = current.next;
114 }
115 }
116 } while (swapped);
117 }
118 }

A class type in C# can be initialized with null or a value which is of a compatible type with the declaration. Lines 76 and 77 look like so
Node previous = null;
Node current = head;
Here the value null is legal. It essentially says "I have no value". The assignment to head is also legal because head is also of type Node. The result is the two references head and current refer to the same Node object value. Modifying the Node instance through one of the references will be visible to the other.

You're assigning previous and next to null and head respectively. It's an assignment operation, just like any other. You don't need to use new unless you're actually creating a new instance of the object.
The generic parts are anything that refers to T. It's a generic type that is supplied when the class is instanciated. A good example is List<T>, which creates a list of objects of type T. You could instance this as List<string> for a list of strings, List<int> for a list of ints, etc.

These are references that could be pointing to instances of a class or can be just null.
You can assign references to other references:
Foo f1 = new Foo();
Foo f2 = f1;
Foo f3 = null;

No objects are being instantiated on lines 76 and 77 in that code. As you said, Node is a class. Classes in .NET are always reference types which means that:
The value of a variable of a reference type is a reference to an object (or nothing).
Variables of a reference type can be assigned the value null, which means that the variable references nothing.
Assigning one variable of a reference type to another variable of a reference type copies the reference, not the object.

Related

Combine multiple realm query results .net

As a Contains implementation, I am using a bit tweaked method written by Andy Dent to query my realm database:
private IQueryable<Entry> FilterEntriesByIds(IQueryable<Entry> allEntries, int[] idsToMatch)
{
// Fancy way to invent Contains<>() for LINQ
ParameterExpression pe = Expression.Parameter(typeof(Entry), "Entry");
Expression chainedByOr = null;
Expression left = Expression.Property(pe, typeof(Entry).GetProperty("Id"));
for (int i = 0; i < idsToMatch.Count(); i++) {
Expression right = Expression.Constant(idsToMatch[i]);
Expression anotherEqual = Expression.Equal(left, right);
if (chainedByOr == null)
chainedByOr = anotherEqual;
else
chainedByOr = Expression.OrElse(chainedByOr, anotherEqual);
}
MethodCallExpression whereCallExpression = Expression.Call(
typeof(Queryable),
"Where",
new Type[] { allEntries.ElementType },
allEntries.Expression,
Expression.Lambda<Func<Entry, bool>>(chainedByOr, new ParameterExpression[] { pe }));
return allEntries.Provider.CreateQuery<Entry>(whereCallExpression);
}
It all works just fine as long as I pass less than 2-3K of ids, when I go with larger amounts the app just crashes with what seems to be a stackoverflow exception.
My first thought to solve this was to break the query into chunks and later combine the results, but the Concat and Union methods do not work on these realm IQueryables, so, how else can I merge such chunked results? Or is there any other workaround?
I can't just convert the results to a List or something and then merge, I have to return realm objects as IQueryable<>
The call stack:
=================================================================
Native Crash Reporting
=================================================================
Got a SIGSEGV while executing native code. This usually indicates
a fatal error in the mono runtime or one of the native libraries
used by your application.
=================================================================
No native Android stacktrace (see debuggerd output).
=================================================================
Basic Fault Address Reporting
=================================================================
Memory around native instruction pointer (0x7c326075c8):0x7c326075b8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x7c326075c8 fd 7b bb a9 fd 03 00 91 a0 0b 00 f9 10 0e 87 d2 .{..............
0x7c326075d8 10 d0 a7 f2 90 0f c0 f2 b0 0f 00 f9 10 00 9e d2 ................
0x7c326075e8 f0 d5 a9 f2 90 0f c0 f2 b0 13 00 f9 a0 a3 00 91 ................
=================================================================
Managed Stacktrace:
============================
=====================================
at Realms.QueryHandle:GroupBegin <0x00000>
at Realms.RealmResultsVisitor:VisitCombination <0x0007f>
at Realms.RealmResultsVisitor:VisitBinary <0x003f7>
at System.Linq.Expressions.BinaryExpression:Accept <0x00073>
at System.Linq.Expressions.ExpressionVisitor:Visit <0x00087>
at Realms.RealmResultsVisitor:VisitCombination <0x000d7>
at Realms.RealmResultsVisitor:VisitBinary <0x003f7>
at System.Linq.Expressions.BinaryExpression:Accept <0x00073>
at System.Linq.Expressions.ExpressionVisitor:Visit <0x00087>
at Realms.RealmResultsVisitor:VisitCombination <0x000d7>
at Realms.RealmResultsVisitor:VisitBinary <0x003f7>
at System.Linq.Expressions.BinaryExpression:Accept <0x00073>
at System.Linq.Expressions.ExpressionVisitor:Visit <0x00087>
at Realms.RealmResultsVisitor:VisitCombination <0x000d7>
at Realms.RealmResultsVisitor:VisitBinary <0x003f7>
at System.Linq.Expressions.BinaryExpression:Accept <0x00073>
at System.Linq.Expressions.Ex
pressionVisitor:Visit <0x00087>
UPD
I found the exact number of elements after which this error gets thrown: 3939, if I pass anything larger than that, it crashes.
I'm not a database expert, just have worked at varying levels (inc Realm) usually on top of someone's lower-level engine. (The c-tree Plus ISAM engine or the C++ core by the real wizards at Realm).
My first impression is that you have mostly-static data and so this is a fairly classical problem where you want a better index generated up front.
I think you can build such an index using Realm but with a bit more application logic.
It sounds a bit like an Inverted Index problem as in this SO question.
For all the single and probably at least double-word combinations which map to your words, you want another table that links to all the matching words. You can create those with a fairly easy loop that creates them from the existing words.
eg: your OneLetter table would have an entry for a that used a one-to-many relationship to all the matching words in the main Words table.
That will delivery a very fast Ilist you can iterate of the matching words.
Then you can flip to your Contains approach at 3 letters or above.
The SQL provider for SQL Server can handle a contains operation with more items than is the limit for maximum number of SQL parameters in one query, which is 2100.
This sample is working:
var ids = new List<int>();
for (int i = 0; i < 10000; i++)
{
ids.Add(i);
}
var testQuery = dbContext.Entity.Where(x => ids.Contains(x.Id)).ToList();
It means, you could try to rewrite your method to use ids.Contains(x.Id).
An example how to do it is in this post.
UPDATE: sorry did not mention this is of Realm, but perhaps it is still worth trying.

C# Translating a few smaller arrays to one big

Title may not explain fully what I want to do, so I made an image.
You can see there are 4 1D arrays(red numbers, black colored numbers are indexes), each of this array goes from 0 to 63. I want to somehow translate them, that for example, index 16 will point to first index of second array.
What I was thinking of, is a function where I give List of arrays and index that I want to get as input, and its returns me the index of array and exact index in this array as output.
I would like to have some hints or suggestions on how to proceed here to achieve this functionality.
Ok, your image shows an interleaved data of 16 elements, so you want to have (showing an example of only two matrices because of space :D)
Global index
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
-----------------------------------------------------------------------------------------------------
Array0 indexes - Array1 indexes
0 1 2 3 4 5 6 7 8 9 A B C D E F - 0 1 2 3 4 5 6 7 8 9 A B C D E F
-------------------------------------------------------------------------------------------------
Global index
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
-----------------------------------------------------------------------------------------------------
Array0 indexes - Array1 indexes
10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F - 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
To get it you can do something like this:
public class CompositeIndex
{
public int ArrayNumber { get; set; }
public int ElementNumber { get; set; }
}
public static CompositeIndex GetIndex(int GlobalIndex, int ArrayCount, int ElementsToInterleave)
{
CompositeIndex index = new CompositeIndex();
int fullArrays = GlobalIndex / ElementsToInterleave; //In your example: 16 / 16 = 1;
index.ArrayNumber = fullArrays % ArrayCount; //In your example: 1 mod 4 = 1;
index.ElementNumber = GlobalIndex - (fullArrays * ElementsToInterleave); //In your example: 16 - (1 * 16) = 0;
return index;
}
Then, if you have 4 matrices and want to get the "global" index 16 you do:
var index = GetIndex(16, 4, 16);
This function allows you to use an indeterminated number of arrays and interleaved elements.
BTW, another time ask better your question, a lot more people will help you if they don't have to solve a puzzles to understand what you want...

Spliting into lines then into variables

i have this text file below:
001 Bulbasaur 45 49 49 65 65 45 Grass Poison
002 Ivysaur 60 62 63 80 80 60 Grass Poison
003 Venusaur 80 82 83 100 100 80 Grass Poison
004 Charmander 39 52 43 60 50 65 Fire
005 Charmeleon 58 64 58 80 65 80 Fire
I have written this piece of code to split it into lines then into variables but it refuses to work, my apology's if i am asking this in the wrong place. (unity C# question).
var lines = textFile.text.Split("\n"[0]);
allMonsters = new Monsters[lines.Length];
List<string> lineSplit = new List<string>();
for (int i = 0; i < lines.Length; i++) {
Debug.Log(lines[i]);
lineSplit.Clear();
lineSplit = lines[i].Split(' ').ToList ();
int ID = int.Parse(lineSplit[0]);
string Name = lineSplit[1].ToString();
float HP = float.Parse(lineSplit[2]);
float ATK = float.Parse(lineSplit[3]);
float DEF = float.Parse(lineSplit[4]);
float SPATK = float.Parse(lineSplit[5]);
float SpDEF = float.Parse(lineSplit[6]);
float speed = float.Parse(lineSplit[7]);
FirstType Ft = (FirstType)System.Enum.Parse(typeof(FirstType),lineSplit[8]);
SecondType ST = (SecondType)System.Enum.Parse(typeof(SecondType),lineSplit[9]); }
The code works for the first line but then on the second run of this code i get null reference to an object error, please help me.
Note, variables are assigned to so they aren't overwritten after code.
EDIT: LineSplit variable is over 1200 elements long, so i do not think unity is clearing the array properly could this be the issue?
I'm not sure about the second iteration, but on the 4th iteration line 004 Charmander 39 52 43 60 50 65 Fire have only 9 parameters (by split of space) and you using lineSplit[9], so there you will get NullPointerException.
When working with text files, linefeed often comes along with carriage return.
Try
var lines = textFile.text.Split(new string[]{"\r\n"}, System.StringSplitOptions.None);
in the first line.

Firmata over nRF24

I'm having some technical problems... I'm trying to use Firmata for arduino but over nrf24, not over Serial interface. I have tested nRF24 communication and it's fine. I have also tested Firmata over Serial and it works.
Base device is simple "serial relay". When it has data available on Serial, read it and send it over nRF24 network. If there is data available from network, read it and send it through Serial.
Node device is a bit complex. It has custom Standard Firmata where I have just added write and read override.
Read override id handeled in loop method in this way:
while(Firmata.available())
Firmata.processInput();
// Handle network data and send it to Firmata process method
while(network.available()) {
RF24NetworkHeader header;
uint8_t data;
network.read(header, &data, sizeof(uint8_t));
Serial.print(data, DEC); Serial.print(" ");
Firmata.processInputOverride(data);
BlinkOnBoard(50);
}
currentMillis = millis();
Firmata processInputOverrride is little changed method of processInput where processInput reads data directly from FirmataSerial, and in this method we pass data down to method from network. This was tested and it should work fine.
Write method is overloaded in a different way. In Firmata.cpp I have added an method pointer that can be set to a custom method and used to send data using that custom method. I have then added custom method call after each of the FirmataSerial.write() call:
Firmata.h
...
size_t (*firmataSerialWriteOverride)(uint8_t);
...
void FirmataClass::printVersion(void) {
FirmataSerial.write(REPORT_VERSION);
FirmataSerial.write(FIRMATA_MAJOR_VERSION);
FirmataSerial.write(FIRMATA_MINOR_VERSION);
Firmata.firmataSerialWriteOverride(REPORT_VERSION);
Firmata.firmataSerialWriteOverride(FIRMATA_MAJOR_VERSION);
Firmata.firmataSerialWriteOverride(FIRMATA_MINOR_VERSION);
}
I have then set the overrided write method to a custom method that just writes byte to network instead of Serial.
size_t ssignal(uint8_t data) {
RF24NetworkHeader header(BaseDevice);
network.write(header, &data, sizeof(uint8_t));
}
void setup() {
...
Firmata.firmataSerialWriteOverride = ssignal;
...
}
Everything seems to be working fine, it's just that some data seems to be inverted or something. I'm using sharpduino (C#) to do some simple digital pin toggle. Here's how output looks like: (< came from BASE, > sent to BASE)
> 208 0
> 209 0
...
> 223 0
> 249
< 4 2 249
and here communication stops...
That last line came inverted. So i tough that I only need to invert received bytes. And it worked for that first command. But then something happens and communication stops again.
> 208 0
> 209 0
...
> 223 0
> 249 // Report firmware version request
< 249 2 4
> 240 121 247 // 240 is sysex begin and 247 is systex end
< 240 121
< 101 0 67 0 0 1 69 0 118
< 117 0 115 0
< 0 70 0 105 0 116 0 111 0 109
< 0 97 0
< 0 109
< 116 0 97 0 247
> 240 107 247
So what could be the problem here? It seems that communication with Firmata works but something isn't right...
-- EDIT --
I solved that issue. The problem was that I didn't see Serial.write() calls in sysex callback. Now that that is solved, I came up to another problem... All stages pass right (I guess) and then I dont get any response from Node when I request pin states
...
< f0 6a 7f 7f 7f ... 7f 0 1 2 3 4 5 6 7 8 9 a b c d e f f7 // analog mapping
> f0 6d 0 f7 // sysex request pin 0 state and value
> f0 6d 1 f7
> f0 6d 2 f7
...
> f0 6d 45 f7
// And I wait for response...
There is no response. Any ideas why would that happen? Node receive all messages correctly and code for handling pin states exist.

Why is my RhinoMocks PartialMock method call not being mocked?

I'm creating a partial mock to test a protected helper method of a base class. I'm not too interested in the debate on whether or not the protected method should be there or if it should be an injected dependency because I'm really interested in seeing the process below work.
EnumerationServiceBase_Accessor is the VSTS 2010 generated private access object. Everything below works well except for the fact that line 17 does not effectively set up an expectation that intercepts the call to CreateNewContextResponse(request), which is the protected method that is being called by partialTarget.EnumerateOp(request) during playback. Instead the actual implementation on the base class is being called. What am I doing wrong here?
1 PrivateObject p = new PrivateObject(mocks.PartialMock<EnumerationServiceBase>(contextManager, requestValidator, configProvider, faultProvider, logger));
2 EnumerationServiceBase_Accessor partialTarget = mocks.PartialMock<EnumerationServiceBase_Accessor>(p);
3
4 EnumerateOpRequest request = new EnumerateOpRequest()
5 {
6 Enumerate = new Enumerate()
7 {
8 Item = new EnumerateNewContext()
9 }
10 };
11
12 using (mocks.Record())
13 {
14 requestValidator.Expect(r => r.ValidateEndTo(request));
15 requestValidator.Expect(r => r.ValidateMaxElements(request, allowNulls: true));
16 partialTarget.Expect(t => t.EnumerateOp(request)).CallOriginalMethod(OriginalCallOptions.CreateExpectation);
17 partialTarget.Expect(t => t.CreateNewContextResponse(request)).Return(null);
18 contextManager.Expect(t => t.RemoveExpiredContexts());
19 }
20
21 using (mocks.Playback())
22 {
23 partialTarget.EnumerateOp(request);
24 }
And this is EnumerateOp(request) as implemented in the EnumerationServiceBase.cs
1 public virtual EnumerateOpResponse EnumerateOp(EnumerateOpRequest request)
2 {
3 EnumerateOpResponse response = null;
4
5 if (request.Enumerate.Item is EnumerateNewContext)
6 {
7 try
8 {
9 _contextManager.RemoveExpiredContexts();
10 }
11 catch (Exception ex)
12 {
13 _logger.Warn("We're not cleaning up contexts effectively.", ex);
14 }
15
16 _requestValidator.ValidateEndTo(request);
17 _requestValidator.ValidateMaxElements(request, allowNulls: true);
18 response = CreateNewContextResponse(request);
19 }
20 else if (request.Enumerate.Item is EnumerationContextType)
21 {
22 _requestValidator.ValidateMaxElements(request, allowNulls: false);
23 response = CreateEnumerationContextResponse(request);
24 }
25 else
26 {
27 throw _faultProvider.GetItemNotRecognizedFault("The Enumerate.Item value was not of type EnumerateNewContext or EnumerationContextType.");
28 }
29 return response;
30 }
EDIT: Removed unnecessary info.
The problem is that your CreateNewContextResponse is protected and You can't mock protected methods with Rhino Mocks.

Categories

Resources