//[TestMore] public bool RemoveData(string key) { long iIdx = 0; int iLen = 0, CurrentIndexSize = GetIndexSize(); if (!ExistsDataKey(key, out iIdx, out iLen)) { return(false); } else { //remove index data, make as dirty IndexObject.Remove(key); SetKeyCount(GetKeyCount() - 1); byte[] idxBytes = FileWrapHelper.GetBytes(IndexObject); //更新索引内容实际大小 if (UpdateDynamicBytes((long)GetNextIndexWriteOffset(), idxBytes, CurrentIndexSize, 24)) { IncrementIndexSize(); UpdateDynamicBytes((long)GetNextIndexWriteOffset(), idxBytes, CurrentIndexSize, 24); _currentDatOffset = GetOffSetDat <int>(_internalReader, 12); CurrentIndexSize = GetIndexSize(); } #region Update Dirty Block SortedList <long, DirtyBlock> dObjs = GetStoreDirtyData(); DirtyBlock dBlock = new DirtyBlock { DataIndex = iIdx, Length = iLen }; if (DirtyObject.ContainsKey(dBlock.DataIndex)) { //[impossible] DirtyObject[dBlock.DataIndex] = dBlock; } else { DirtyObject.Add(dBlock.DataIndex, dBlock); } byte[] dBytes = FileWrapHelper.GetBytes(DirtyObject); if (UpdateDynamicBytes((long)(HEAD_SUMMARY_BYTES + CurrentIndexSize), dBytes, MAX_DIRTYBLOCK_SIZE, HEAD_SUMMARY_BYTES - 9)) { ClearDirtyData(); UpdateDynamicBytes((long)(HEAD_SUMMARY_BYTES + CurrentIndexSize), dBytes, MAX_DIRTYBLOCK_SIZE, HEAD_SUMMARY_BYTES - 9); } #endregion return(true); } }
private void BuildEmptyFile() { _internalWriter.Write(Encoding.ASCII.GetBytes("KVS 1.0 ")); //文件版本 +8 _internalWriter.Write(BitConverter.GetBytes(HeadIndexLength)); //索引空间长度 +4 _internalWriter.Write(BitConverter.GetBytes((int)0)); //数据索引偏移量 +4 _internalWriter.Write(BitConverter.GetBytes((long)0)); //下次写入数据索引 +8 byte[] idxBytes = FileWrapHelper.GetBytes(new SortedList <string, KeyValueState>(StringComparer.Ordinal)); KeepPositionWrite(HEAD_SUMMARY_BYTES, idxBytes); _internalWriter.Write(BitConverter.GetBytes(idxBytes.Length)); //索引有效数据长度 +4 _internalWriter.Write(BitConverter.GetBytes(MAX_DIRTYBLOCK_SIZE)); //DirtyBlock空间长度 +4 byte[] dbBytes = FileWrapHelper.GetBytes(new SortedList <long, DirtyBlock>()); KeepPositionWrite(HEAD_SUMMARY_BYTES + HeadIndexLength, dbBytes); _internalWriter.Write(BitConverter.GetBytes(dbBytes.Length)); //DirtyBlock有效数据长度 +4 _internalWriter.Write(BitConverter.GetBytes((int)0)); //所有键值总数 +4 _internalWriter.Write('\n'); // +1 }
//[TestMore] public bool StoreKeyData(string key, byte[] kDat) { long iIdx = 0; int iLen = 0, CurrentIndexSize = GetIndexSize(); //Read long nDataIndex = GetOffSetDat <long>(_internalReader, 16); if (nDataIndex == 0) { nDataIndex = HEAD_SUMMARY_BYTES + (long)CurrentIndexSize + MAX_DIRTYBLOCK_SIZE; } //Console.WriteLine("Store Index: {0}", nDataIndex); bool addNew = false, append = false; SortedList <string, KeyValueState> idxObj = GetIndexObject(null); KeyValueState kState = new KeyValueState(); kState.Key = key; kState.Length = kDat.Length; if (idxObj == null) { IndexObject = new SortedList <string, KeyValueState>(StringComparer.Ordinal); addNew = true; } else { if (!ExistsDataKey(key, out iIdx, out iLen)) { addNew = true; append = true; //Console.WriteLine("Note Exists Key" + key); } else { KeyValueState oldState = IndexObject[key]; if ((oldState.Length + oldState.ChipSize) >= kDat.Length) { append = false; //Location Update nDataIndex = oldState.DataIndex + _currentDatOffset; kState.DataIndex = oldState.DataIndex; kState.ChipSize = (oldState.Length + oldState.ChipSize) - kDat.Length; } else { kState.ChipSize = 0; Console.WriteLine("old:{0}, new:{1}, other:{2}", oldState.DataIndex, nDataIndex, nDataIndex - _currentDatOffset); if (nDataIndex == (oldState.DataIndex + _currentDatOffset + oldState.Length + oldState.ChipSize)) { append = false; nDataIndex = oldState.DataIndex + _currentDatOffset; kState.DataIndex = oldState.DataIndex; //下次写入数据索引 KeepPositionWrite(16, BitConverter.GetBytes(nDataIndex + kDat.LongLength)); //Console.WriteLine("Location Append"); } else { append = true; SortedList <long, DirtyBlock> dirtyDat = GetStoreDirtyData(); #region Dirty Block DirtyBlock dBlock = new DirtyBlock { DataIndex = oldState.DataIndex, Length = oldState.Length + kState.ChipSize }; //Console.WriteLine("Dirty: {0}+{1}", dBlock.DataIndex, dBlock.Length); if (DirtyObject.ContainsKey(dBlock.DataIndex)) { //[impossible] DirtyObject[dBlock.DataIndex] = dBlock; } else { DirtyObject.Add(dBlock.DataIndex, dBlock); } byte[] dBytes = FileWrapHelper.GetBytes(DirtyObject); if (UpdateDynamicBytes((long)(HEAD_SUMMARY_BYTES + CurrentIndexSize), dBytes, MAX_DIRTYBLOCK_SIZE, HEAD_SUMMARY_BYTES - 9)) { ClearDirtyData(); UpdateDynamicBytes((long)(HEAD_SUMMARY_BYTES + CurrentIndexSize), dBytes, MAX_DIRTYBLOCK_SIZE, HEAD_SUMMARY_BYTES - 9); } #endregion } } } } if (append) { //在DirtyBlock总查找可用空间(TODO) storeStream.SetLength(storeStream.Length + kDat.Length); //下次写入数据索引 KeepPositionWrite(16, BitConverter.GetBytes(nDataIndex + kDat.LongLength)); //Console.WriteLine("test:{0}, {1}, {2}", nDataIndex, _currentDatOffset, nDataIndex - _currentDatOffset); kState.DataIndex = nDataIndex - _currentDatOffset; } if (addNew) { kState.ChipSize = 0; IndexObject.Add(key, kState); SetKeyCount(GetKeyCount() + 1); //Console.WriteLine("ADD New: Set {0}", GetKeyCount()); } else { IndexObject[key] = kState; } byte[] idxBytes = FileWrapHelper.GetBytes(IndexObject); bool blnIndxAdd = false; //更新索引内容实际大小 if (UpdateDynamicBytes((long)GetNextIndexWriteOffset(), idxBytes, CurrentIndexSize, 24)) { IncrementIndexSize(); nDataIndex += INDEX_INCREMENT_STEP; UpdateDynamicBytes((long)GetNextIndexWriteOffset(), idxBytes, CurrentIndexSize, 24); _currentDatOffset = GetOffSetDat <int>(_internalReader, 12); blnIndxAdd = true; } //Console.WriteLine("DataOffSet: {0}", _currentDatOffset); //Console.WriteLine("Store Index: {0}", nDataIndex); KeepPositionWrite(nDataIndex, kDat); //修改下次写入位置 if (blnIndxAdd == true) { KeepPositionWrite(16, BitConverter.GetBytes(nDataIndex + kDat.LongLength)); } return(true); }