Skip to content

Commit

Permalink
Move String.Searching.cs to shared CoreLib partition (dotnet/corert#4673
Browse files Browse the repository at this point in the history
)

Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
  • Loading branch information
jkotas committed Oct 4, 2017
1 parent 2de0bce commit 238907f
Show file tree
Hide file tree
Showing 6 changed files with 170 additions and 278 deletions.
232 changes: 0 additions & 232 deletions src/classlibnative/bcltype/stringnative.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,6 @@
#pragma optimize("tgy", on)
#endif


#define PROBABILISTICMAP_BLOCK_INDEX_MASK 0X7
#define PROBABILISTICMAP_BLOCK_INDEX_SHIFT 0x3
#define PROBABILISTICMAP_SIZE 0X8

//
//
// FORWARD DECLARATIONS
//
//
int ArrayContains(WCHAR searchChar, __in_ecount(length) const WCHAR *begin, int length);
void InitializeProbabilisticMap(int* charMap, __in_ecount(length) const WCHAR* charArray, int length);
bool ProbablyContains(const int* charMap, WCHAR searchChar);
bool IsBitSet(int value, int bitPos);
void SetBit(int* value, int bitPos);

//
//
// CONSTRUCTORS
Expand Down Expand Up @@ -295,116 +279,6 @@ FCIMPL6(INT32, COMString::CompareOrdinalEx, StringObject* strA, INT32 indexA, IN
}
FCIMPLEND

/*===============================IndexOfCharArray===============================
**Action:
**Returns:
**Arguments:
**Exceptions:
==============================================================================*/
FCIMPL4(INT32, COMString::IndexOfCharArray, StringObject* thisRef, CHARArray* valueRef, INT32 startIndex, INT32 count )
{
FCALL_CONTRACT;

VALIDATEOBJECT(thisRef);
VALIDATEOBJECT(valueRef);

if (thisRef == NULL)
FCThrow(kNullReferenceException);

WCHAR *thisChars;
WCHAR *valueChars;
int valueLength;
int thisLength;

thisRef->RefInterpretGetStringValuesDangerousForGC(&thisChars, &thisLength);

int endIndex = startIndex + count;

valueLength = valueRef->GetNumComponents();
valueChars = (WCHAR *)valueRef->GetDataPtr();

// use probabilistic map, see (code:InitializeProbabilisticMap)
int charMap[PROBABILISTICMAP_SIZE] = {0};

InitializeProbabilisticMap(charMap, valueChars, valueLength);

for(int i = startIndex; i < endIndex; i++) {
WCHAR thisChar = thisChars[i];
if (ProbablyContains(charMap, thisChar))
if (ArrayContains(thisChars[i], valueChars, valueLength) >= 0) {
FC_GC_POLL_RET();
return i;
}
}

FC_GC_POLL_RET();
return -1;
}
FCIMPLEND

/*=============================LastIndexOfCharArray=============================
**Action:
**Returns:
**Arguments:
**Exceptions:
==============================================================================*/

FCIMPL4(INT32, COMString::LastIndexOfCharArray, StringObject* thisRef, CHARArray* valueRef, INT32 startIndex, INT32 count )
{
FCALL_CONTRACT;

VALIDATEOBJECT(thisRef);
VALIDATEOBJECT(valueRef);
WCHAR *thisChars, *valueChars;
int thisLength, valueLength;

if (thisRef==NULL) {
FCThrow(kNullReferenceException);
}

if (valueRef == NULL)
FCThrowArgumentNull(W("anyOf"));

thisRef->RefInterpretGetStringValuesDangerousForGC(&thisChars, &thisLength);

if (thisLength == 0) {
return -1;
}

if (startIndex < 0 || startIndex >= thisLength) {
FCThrowArgumentOutOfRange(W("startIndex"), W("ArgumentOutOfRange_Index"));
}

if (count<0 || count - 1 > startIndex) {
FCThrowArgumentOutOfRange(W("count"), W("ArgumentOutOfRange_Count"));
}


valueLength = valueRef->GetNumComponents();
valueChars = (WCHAR *)valueRef->GetDataPtr();

int endIndex = startIndex - count + 1;

// use probabilistic map, see (code:InitializeProbabilisticMap)
int charMap[PROBABILISTICMAP_SIZE] = {0};

InitializeProbabilisticMap(charMap, valueChars, valueLength);

//We search [startIndex..EndIndex]
for (int i=startIndex; i>=endIndex; i--) {
WCHAR thisChar = thisChars[i];
if (ProbablyContains(charMap, thisChar))
if (ArrayContains(thisChars[i],valueChars, valueLength) >= 0) {
FC_GC_POLL_RET();
return i;
}
}

FC_GC_POLL_RET();
return -1;

}
FCIMPLEND

/*==================================GETCHARAT===================================
**Returns the character at position index. Thows IndexOutOfRangeException as
Expand Down Expand Up @@ -447,112 +321,6 @@ FCIMPL1(INT32, COMString::Length, StringObject* str) {
FCIMPLEND


// HELPER METHODS
//
//
// A probabilistic map is an optimization that is used in IndexOfAny/
// LastIndexOfAny methods. The idea is to create a bit map of the characters we
// are searching for and use this map as a "cheap" check to decide if the
// current character in the string exists in the array of input characters.
// There are 256 bits in the map, with each character mapped to 2 bits. Every
// character is divided into 2 bytes, and then every byte is mapped to 1 bit.
// The character map is an array of 8 integers acting as map blocks. The 3 lsb
// in each byte in the character is used to index into this map to get the
// right block, the value of the remaining 5 msb are used as the bit position
// inside this block.
void InitializeProbabilisticMap(int* charMap, __in_ecount(length) const WCHAR* charArray, int length) {
LIMITED_METHOD_CONTRACT;

_ASSERTE(charMap != NULL);
_ASSERTE(charArray != NULL);
_ASSERTE(length >= 0);

bool hasAscii = false;

for(int i = 0; i < length; ++i) {
int hi,lo;

int c = charArray[i];

lo = c & 0xFF;
hi = (c >> 8) & 0xFF;

int* value = &charMap[lo & PROBABILISTICMAP_BLOCK_INDEX_MASK];
SetBit(value, lo >> PROBABILISTICMAP_BLOCK_INDEX_SHIFT);

if (hi > 0) {
value = &charMap[hi & PROBABILISTICMAP_BLOCK_INDEX_MASK];
SetBit(value, hi >> PROBABILISTICMAP_BLOCK_INDEX_SHIFT);
}
else {
hasAscii = true;
}
}

if (hasAscii) {
// Common to search for ASCII symbols. Just the high value once.
charMap[0] |= 1;
}
}

// Use the probabilistic map to decide if the character value exists in the
// map. When this method return false, we are certain the character doesn't
// exist, however a true return means it *may* exist.
inline bool ProbablyContains(const int* charMap, WCHAR searchValue) {
LIMITED_METHOD_CONTRACT;

int lo, hi;

lo = searchValue & 0xFF;
int value = charMap[lo & PROBABILISTICMAP_BLOCK_INDEX_MASK];

if (IsBitSet(value, lo >> PROBABILISTICMAP_BLOCK_INDEX_SHIFT)) {
hi = (searchValue >> 8) & 0xFF;
value = charMap[hi & PROBABILISTICMAP_BLOCK_INDEX_MASK];

return IsBitSet(value, hi >> PROBABILISTICMAP_BLOCK_INDEX_SHIFT);
}

return false;
}

inline void SetBit(int* value, int bitPos) {
LIMITED_METHOD_CONTRACT;

_ASSERTE(bitPos <= 31);

*value |= (1 << bitPos);
}

inline bool IsBitSet(int value, int bitPos) {
LIMITED_METHOD_CONTRACT;

_ASSERTE(bitPos <= 31);

return (value & (1 << bitPos)) != 0;
}


/*================================ArrayContains=================================
**Action:
**Returns:
**Arguments:
**Exceptions:
==============================================================================*/
int ArrayContains(WCHAR searchChar, __in_ecount(length) const WCHAR *begin, int length) {
LIMITED_METHOD_CONTRACT;
_ASSERTE(begin != NULL);
_ASSERTE(length >= 0);

for(int i = 0; i < length; i++) {
if(begin[i] == searchChar) {
return i;
}
}
return -1;
}


/*================================ReplaceString=================================
**Action:
**Returns:
Expand Down
4 changes: 0 additions & 4 deletions src/classlibnative/bcltype/stringnative.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,6 @@ class COMString {

static FCDECL6(INT32, CompareOrdinalEx, StringObject* strA, INT32 indexA, INT32 countA, StringObject* strB, INT32 indexB, INT32 countB);

static FCDECL4(INT32, LastIndexOfCharArray, StringObject* thisRef, CHARArray* valueRef, INT32 startIndex, INT32 count );

static FCDECL4(INT32, IndexOfCharArray, StringObject* vThisRef, CHARArray* value, INT32 startIndex, INT32 count );

static FCDECL2(FC_CHAR_RET, GetCharAt, StringObject* pThisRef, INT32 index);
static FCDECL1(INT32, Length, StringObject* pThisRef);

Expand Down
1 change: 0 additions & 1 deletion src/mscorlib/System.Private.CoreLib.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,6 @@
<Compile Include="$(BclSourcesRoot)\System\String.cs" />
<Compile Include="$(BclSourcesRoot)\System\String.Comparison.cs" />
<Compile Include="$(BclSourcesRoot)\System\String.Manipulation.cs" />
<Compile Include="$(BclSourcesRoot)\System\String.Searching.cs" />
<Compile Include="$(BclSourcesRoot)\System\Text\StringBuilder.CoreCLR.cs" />
<Compile Include="$(BclSourcesRoot)\System\Text\StringBuilderCache.cs" />
<Compile Include="$(BclSourcesRoot)\System\Exception.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,7 @@
<Compile Include="$(MSBuildThisFileDirectory)System\Single.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Span.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Span.NonGeneric.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\String.Searching.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\StringSpanHelpers.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\StackOverflowException.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\StringComparer.cs" />
Expand Down
Loading

0 comments on commit 238907f

Please sign in to comment.