2017-11-11 80 views
0

我讀過幾個鏈接來實現使用Cassandra c#驅動程序進行手動分頁。如何在Cassandra c#驅動中存儲分頁狀態?

鏈接簡稱:

Backward paging in cassandra c# driver

https://datastax.github.io/csharp-driver/features/paging/

我的要求:

我試圖讓所有不同分區鍵的列表形式表,其尺寸過大。

由於大小Cassandra db在檢索它們或執行第一次查詢時發生錯誤。現在假設在獲取100000個不同的分區鍵後失敗,我將使用Cassandra c#驅動程序提供的分頁狀態。

現在我正在保存最後一個可用的頁面狀態,然後再無法記錄文件並再次使用它從失敗的地方繼續。

Encoding.ASCII.GetString(pagingState); 

而且使用檢索格式的日誌文件:

Encoding.ASCII.GetBytes(pagingState); 

但是,當我將它傳遞給.SetPagingState(pagingState)

我使用節省了尋呼狀態到日誌文件執行查詢會拋出異常:

java.lang.IllegalState例外情況:無法調用hasNext(),直到 以前的迭代器已保存到文件之前從文件中檢索後,他們已經完全消耗

我相比,字節數組字節。字節數組中的幾個值是不同的。 我試過用UIF8編碼但沒用。

注意:它的作品完美時,我通過字節數組而不轉換。我的意思是下面的條件代碼完美地工作。

if (pagingState != null) 
{ 
    GenerateInitialLogs(pagingState); 
} 

全功能:

private void BtnGetPrimaryKeys_Click(object sender, EventArgs e) 
    { 
     string fileContent = File.ReadAllText("D:/Logs/log.txt");    
     if(fileContent.Length > 0) 
     { 
      GenerateInitialLogs(Encoding.ASCII.GetBytes(fileContent)); 
     } 
     else 
     { 
      GenerateInitialLogs(null); 
     } 
    } 

    private void Log(byte[] pagingState) 
    { 
     File.WriteAllText("D:/Logs/log.txt", Encoding.ASCII.GetString(pagingState));  
    } 

    private int GenerateInitialLogs(byte[] pagingState) 
    {    
     try 
     { 
      RowSet rowSet = BLL.SelectDistinctPrimaryKeys(pagingState); 

      List<PrimaryKey> distinctPrimaryKeys = new List<PrimaryKey>(); 
      foreach (Row row in rowSet) 
      { 
       if (rowSet.PagingState != null) { pagingState = new byte[rowSet.PagingState.Length]; } 
       pagingState = rowSet.PagingState; 
      } 
      Log(pagingState) 

      if (pagingState != null) 
      { 
       GenerateInitialLogs(pagingState); 
      } 
     } 
     catch(Exception ex) 
     { 
      throw ex; 
     } 
    } 

    public static RowSet SelectDistinctPrimaryKeysFromTagReadings(byte[] pagingState) 
    { 
     try 
     { 
      // will execute on continuing after failing in between. 
      if (pagingState != null) 
      { 
       PreparedStatement preparedStatement = BLL.currentSession.Prepare("SELECT DISTINCT \"Url\",\"Id\" FROM \"Readings\" "); 
       BoundStatement boundStatement = preparedStatement.Bind(); 
       IStatement istatement = boundStatement.SetAutoPage(false).SetPageSize(1000).SetPagingState(pagingState); 
       return BLL.currentSession.Execute(istatement); 
      } 
      else 
      { 
       PreparedStatement preparedStatement = BLL.currentSession.Prepare("SELECT DISTINCT \"Url\",\"Id\" FROM \"Readings\" "); 
       BoundStatement boundStatement = preparedStatement.Bind(); 
       IStatement istatement = boundStatement.SetAutoPage(false).SetPageSize(1000); 
       return BLL.currentSession.Execute(istatement);      
      } 
     } 
     catch (Exception ex) 
     { 
      throw ex; 
     } 
    } 
+0

對我來說,將分頁狀態存儲在日誌文件中似乎不是個好主意。你真的必須把它存儲在內存以外的任何地方嗎?我也不覺得你的代碼示例添加了任何東西,因爲它是從日誌文件中存儲/獲取的東西,可以解決這些問題。你可以包含完整的代碼示例嗎? –

+0

@SimonFontanaOscarsson你爲什麼認爲它會弄亂的東西。每次形式文件時,我都沒有閱讀分頁狀態。我正在用最新的分頁狀態更新它。這裏我的頁面大小是1000,現在每獲取1000條記錄,它將更新日誌。它只會在關閉中間應用程序並再次重新啓動時從日誌文件讀取分頁狀態。我正在使用Windows應用程序。我添加了2個函數一個日誌,其他的是按鈕點擊事件。 –

+0

@SimonFontanaOscarsson哦..還有一件事我忘了提。這是它會工作,當我傳遞字節數組,因爲它是。我的意思是,如果 (pagingState!= null) { GenerateInitialLogs(pagingState); } 工作正常。只有轉換有問題。我會更新有關的詳細信息。 –

回答

1

該解決方案是不是我想通了。它由Jorge Bay Gondra(datastax的僱員)完成。

原來的答覆:

https://groups.google.com/a/lists.datastax.com/forum/#!topic/csharp-driver-user/4XWTXZC-hyI

解決方案:

無法將其轉換成ASCII或UIF8或任何編碼,因爲他們並不代表文本。

使用這些函數將字節數組轉換爲十六進制數據,反之亦然。

public static string ByteArrayToHexaDecimalString(byte[] bytes) 
{ 
    StringBuilder stringBuilder = new StringBuilder(bytes.Length * 2); 
    foreach (byte b in bytes) { stringBuilder.AppendFormat("{0:x2}", b); } 
    return stringBuilder.ToString(); 
} 

public static byte[] HexaDecimalStringToByteArray(String hexaDecimalString) 
{ 
    int NumberChars = hexaDecimalString.Length; 
    byte[] bytes = new byte[NumberChars/2]; 
    for (int i = 0; i < NumberChars; i += 2) 
    { 
     bytes[i/2] = Convert.ToByte(hexaDecimalString.Substring(i, 2), 16); 
    } 
    return bytes; 
}