I have a problem with ServiceStack.CacheAccess.Memcached.MemcachedClientCache.
The Increment method does not work as expected.
For the test, I am using a regular console app and the ICacheClient interface.
According to the method documentation :
The item must be inserted into the cache before it can be changed.
The item must be inserted as a System.String.
The operation only works with System.UInt32values, so -1 always indicates that the item was not found.
So here we go:
ICacheClient client = new MemcachedClientCache();
string key = "test";
bool result = client.Remove(key);
Console.WriteLine("{0} removed: {1}", key, result);
//The item must be inserted as a System.String.
result = client.Add(key, "1");
Console.WriteLine("added {0}", result);
long v = client.Increment(key, 1);
Console.WriteLine("first increment : {0}", v);
string o = client.Get<string>(key);
Console.WriteLine("first read: {0}", o);
v = client.Increment(key, 1);
Console.WriteLine("second increment: {0}", v);
o = client.Get<string>(key);
Console.WriteLine("second read: {0}", o);
The result :
test removed: True
added True
first increment : 0
first read: 1
second increment: 0
second read: 1
As you can see, increment does not works.
The config for enyim:
<enyim.com>
<memcached protocol="Binary">
<servers>
<!-- make sure you use the same ordering of nodes in every configuration you have -->
<add address="memcached-dev1"
port="11211" />
</servers>
<socketPool minPoolSize="10"
maxPoolSize="100"
connectionTimeout="00:00:10"
deadTimeout="00:02:00" />
</memcached>
</enyim.com>
Did I missed something ?
You can not read the value of a counter in this manner, there is an explanation of why in one of the closed issues of the Enyim project (here). Instead just increment the counter by 0.
var v = cacheClient.Increment(key, 0);
Related
I have a list declared outside a for loop and then I assign some values to this list inside that for loop and its value is updated when printed inside the loop but when I print it after the loop, it gives me an empty list.
List<List<String>> chunkSizeCollection(List<String> followedList) {
int counter = 0;
int ongoingCounter = 0;
bool isLessThanTen = false;
List<List<String>> returnAbleChunkedList = [];
List<String> midList = [];
log("in followedlist");
followedList.forEach((element) {
if (counter == 0) {
int difference = followedList.length - ongoingCounter;
if (difference < 10) {
// log("in difference if: $difference");
isLessThanTen = true;
}
}
midList.add(element);
counter++;
ongoingCounter++;
if (counter == 10 || (isLessThanTen && ongoingCounter == followedList.length)) {
returnAbleChunkedList.add(midList);
log("returnAbleChunkedList in counter 10 after adding new val is: $returnAbleChunkedList");
//above log works properly and prints the updated list
midList.clear();
counter = 0;
}
});
//this log on the other hand, returns an empty list
log("returnAbleChunkedList: $returnAbleChunkedList before return");
return returnAbleChunkedList;
}
The output:
[log] returnAbleChunkedList in counter 10 after adding new val is: [[KQTuEPllbmRrlBNvYgZ7oUXwtA63, OZUZOE10IzT8quUFoZbNxZOynU32, fCYIlYemCvbLTc7SpNHw6fCHrcm1, CbcLrtDNOdYZyC23FzEehOrJbKx2, FFvvVHCpPGNKUiXPQD34QdoPqH32, Gk09y59vSVXa1HNhzYvc6Atqnt53, JDO356z8urYQvuktJmc6eNUYqSm2, YesvvNI43gUVYPMfqhG4uRO5t6K2]]
[log] returnAbleChunkedList: [[]] before return
In this line:
returnAbleChunkedList.add(midList);
you add a reference to midList to your output list. If your input is longer than 10, you'll end up adding more than one reference to midList to the output list (i.e. you might now have 2). Subsequently, you clear midList so you now have an output list that contains 2 references to a list that you've now cleared, so you end up with a list containing 2 empty lists.
If, instead, you changed this to:
returnAbleChunkedList.add(midList.toList());
you'd add a copy of midList to your output list and your end up with:
[[a, b, c, d, e, f, g, h, i, j], [k]]
as you expected.
The problem is this:
returnAbleChunkedList.add(midList);
midList.clear();
You add the object midlist to the list and then you clear it. So the object you added will be emptied. You have to create a copy or add the elements of the list.
returnAbleChunkedList.add(midList.toList());
// or
returnAbleChunkedList.add(List.of(midList));
// or
returnAbleChunkedList.add([...midList]);
I have a strange problem when I use a for loop to add element in to the java.util.ArrayList , but the list's address of the reference always changing
Here is the code:
var curntRow: Row = null
var startTime: lang.Long = null
//this is the list
var standTime: util.ArrayList[Row] = new util.ArrayList[Row]()
for (row <- usersCoorOrderByTime) {
if (curntRow == null) {
startTime = row.getAs[lang.Long](2)
} else if (!row.getAs[String](1).equals(curntRow.getAs[String](1))) {
//And I use the method list.add() right here
standTime.add(Row(row.getAs[String](0), row.getAs[String](1), row.getAs[DoubleType](4), row.getAs[DoubleType](5), curntRow.getAs[lang.Long](2) - startTime))
startTime = row.getAs[lang.Long](2)
}
curntRow = row
}
And please see the pic that I debug below:
addr is "7703"
Before get in the loop The list's addr is "7703"
When is get in the loop ,the address changes
change to "11268"
change to "11287"
The most strange things is when it end the loop, the address has changed back to where it was originally declared
change back to "7703"
finally I get an empty ArrayList
I found the error
the parameter of for loop is Dataframe, I should turn to Array or List then make for loop
Try using Mutable ArrayBuffer. Below is a simple example. I hope it helps.
val x = scala.collection.mutable.ArrayBuffer[String]()
x += "2"
x += "4"
println(x)
using UnityEngine;
using System.Collections;
public class NewMonoBehaviour1 : MonoBehaviour
{
void ConcatExample(int[] intArray)
{
string line = intArray[0].ToString(); // the line is the var of the first in array
for(i =1;i <intArray.Length; i++) // the length is unknown ?
{
line += ", " + intArray[i].ToString(); //
}
return line;
//each time allocate new in original place
}
}
How can this function work ? the length of array is unknown , so how the for loop works ?Besides, this is void function but shouldn't return anythings right ,or is there any exceptional case ,finally,according to the unity manual, it is said that the function will keep producing a string but with new contents in the same place , resulting in consuming large memory space .Why ?thx
What makes you think that the Length should be unknown? It is a property that any array simply has
Gets the total number of elements in all the dimensions of the Array.
Of course it is not unknown the moment you call your method with an according parameter!
The return line; will not even compile since as you say the method is of type void so it can not return anything. It should probably be private string ConcatExample
Then what the unity manual (don't know where exactly you read this) means lies in
line += ", " + intArray[i].ToString();
under the hood every string in c# is an immutable char[]. So everytime you do a string concatenation via stringC = stringA + stringB what happens under the hood is basically something similar to
char[] stringC = new char[stringA.Length + stringB.Length];
for(var iA = 0; iA < stringA.Length; iA++)
{
stringC[i] = stringA[i];
}
for(var iB = 0; iB < stringB.Length; iB++)
{
stringC[iB + stringA.Length] = stringB[iB];
}
so whenever dealing with loops especially with large data it is strongly recommended to rather use a StringBuilder like
private string ConcatExample(int[] intArray)
{
var builder = new StringBuilder(intArray[0]);
for(i =1; i < intArray.Length; i++)
{
builder.Append(", ").Append(intArray[i].ToString());
}
return builder.ToString();
}
The length of the array will be the length of the array of ints you pass into the function as an argument.
say you pass it
Int[] ints = {1,2,3}
ConcatExample(ints); //the length of the array is now 3
add a debug.log() function to the ConcatExample method
void ConcatExample(int[] intArray)
{
string line = intArray[0].ToString();
for (int i = 1; i < intArray.Length; i++)
{
line += ", " + intArray[i].ToString(); //
Debug.Log(line);
}
}
debug.log would produce the following in the console
1, 2
1, 2, 3
and finally the return line; at the end would just result in an error because yes you are correct void returns nothing
This function CANNOT work, unless it gets the data it expects. A NULL passed to this function, for example, would generate a runtime null-reference exception. Passing a valid integer array, of length zero would generate an invalid index error on the first line.
You are correct, the function returns nothing, and appears pointless. In fact, I would have expected return line; to generate a complier error.
The string type appears "dynamic" meaning, it will indeed allocate more and more memory as needed. Technically, it is actually the string "+" operator, (a function that takes two strings as parameters) that is allocating this space. This function returns a new string, of the appropriate size. The garbage collector will DEallocate "old" strings when they are no longer referenced by any variables.
The System.Author Windows property is a multiple value string. Windows Search returns this value as an array of strings in a DataColumn. (The column's data-type is string[] or String().) When I call the WriteXML method on the resulting data-table, I get the following InvalidOperationException exception.
Is there a way to specify the data-table's xml-serializer to use for specific columns or specific data-types?
Basically, how can I make WriteXML work with this data-table?
System.InvalidOperationException:
Type System.String[] does not
implement IXmlSerializable interface
therefore can not proceed with
serialization.
You could easily copy your DataTable changing the offending Authors column to a String and joing the string[] data with a proper delimiter like "|" or "; ".
DataTable xmlFriendlyTable = oldTable.Clone();
xmlFriendlyTable.Columns["Author"].DataType = typeof(String);
xmlFriendlyTable.Columns["Author"].ColumnMapping = MappingType.Element;
foreach(var row in oldTable.Rows) {
object[] rowData = row.ItemArray;
object[] cpyRowData = new object[rowData.Length];
for(int i = 0; i<rowData.Length; i++) {
if(rowData[i] != null && rowData[i].GetType() == typeof(String[])) {
cpyRowData[i] = String.Join("; ", (rowData[i] as String[]));
} else {
cpyRowData[i] = rowData[i];
}
xmlFriendlyTable.Rows.Add(cpyRowData);
}
}
xmlFriendlyTable.WriteXml( ... );
NOTE Wrote the above in the web browser, so there may be syntax errors.
i have created web application and using textbox and it can contains multiple line of data becoz i have set its textmode property is multiline.
my problem is that i want to check each line contain data or not so i using count variable which count how many line contain data.
string[] data;
int cntindex;
data = txt_invoicenumber.Text.ToString().Split("\n".ToCharArray());
cntindex = data.Length;
for (j = 0; j < cntindex; j++)
{
if (data[j]!="")
{
inv_count++;
}
}
Its not working.
Please help me.
I guess this is because new line is \r\n so there is a '\r' also on empty lines.
Change the if statement to:
if (data[j].Trim().Length != 0)
Firstly, You don't need to ToString() the .Text property as it is already a string.
try this
string[] lines = txt_invoicenumber.Text.Split(Environment.NewLine);
int lineCount = 0;
foreach(string line in lines)
{
if(!string.IsNullOrEmpty(line))
{
lineCount ++;
this.ProcessLine(line);
}
}
var lb = new String[] { "\r\n" };
var lines = txt_invoicenumber.Text.Split(lb, StringSplitOptions.None).Length;
This will count empty lines too. If you don't want to count empty lines, use the StringSplitOptions.RemoveEmptyEntries value.
Don't count 100% on "\r\n" if you have little control over your environment though.
This is the answer I came up with.
String[] lines = TextBox1.Text.Split(new Char[] { '\r', '\n' },
StringSplitOptions.RemoveEmptyEntries);
Int32 validLineCount = lines.Length;